# Coding standards

## Environment setup

* Ensure that the user has direnv installed, and that it is set up correctly in their shell. See https://direnv.net/docs/installation.html
* Ensure that the user has Nix installed, and that it is set up correctly. See https://nixos.org/download.html
* Ensure that the user has the direnv VS code extension installed, so that the `.envrc` file is automatically loaded when the project is opened in VS Code.

### Background

templ has an `.envrc` file that is used to set up the development environment using a tool called `direnv`. There is a VS Code extension available that will automatically load this when you open the project in VS Code.

The `.envrc` file uses a Nix flake to set up the environment, so Nix is required to be installed.

The version of Go used is defined in the `flake.nix` file.

## Build tasks

templ uses the `xc` task runner - https://github.com/joerdav/xc

If you run `xc` you can get see a list of the development tasks that can be run, or you can read the `README.md` file and see the `Tasks` section.

The most useful tasks for local development are:

* `xc install-snapshot` - builds the templ CLI and installs it into `~/bin`. Ensure that this is in your path.
* `xc generate` - generates Go code from the templ files in the project.
* `xc test` - regenerates all templates, and runs the unit tests.
* `xc fmt` - runs `gofmt` to format all Go code.
* `xc lint` - run the same linting as run in the CI process.
* `xc docs-run` - run the Docusaurus documentation site.

templ has a code generation step, this is automatically carried out using `xc test`.

Don't install templ globally using `xc install-snapshot` or `go install`. Use the `xc generate` or `xc test` tasks to generate the code, which will also run the tests.

## Commit messages

The project using https://www.conventionalcommits.org/en/v1.0.0/

Examples:

* `feat: support Go comments in templates, fixes #234"`
* `fix: ensure that the templ CLI works with Go 1.21, fixes #123`

## Documentation

* Documentation is written in Markdown, and is rendered using Docusaurus. The documentation is in the `docs` directory.
* Update documentation when the behaviour of templ changes, or when new features are added.

## Writing style

* Use American English spelling to match the Go standard library, and HTML spec, e.g. "color".
* Use the Oxford comma, e.g. "apples, oranges, and bananas".
* Avoid use of emojis everywhere - in code, comments, commit messages, and documentation.
* Be "to the point" and precise - avoid unnecessary words, don't use filler words like "just" or "really".
* Use the active voice, e.g. "templ generates code" rather than "code is generated by templ".
* Don't use emphatic words or phrases like "very", "blazingly fast", etc.

## Coding style

* Reduce nesting - i.e. prefer early returns over an `else` block, as per https://danp.net/posts/reducing-go-nesting/ or https://go.dev/doc/effective_go#if
* Use line breaks to separate "paragraphs" of code - don't use line breaks in between lines, or at the start/end of functions etc.
* Use the `xc fmt` and `xc lint` build tasks to format and lint code before committing.
* Don't use unnecessary comments that explain what the code does.
* If comments are used, ensure that they are full sentences, and use proper punctuation, including ending with a full stop.

## Tests

* Tests for generated code are in the `./generator` directory. Each test is in a subdirectory.
* Tests for the templ CLI are in the `./cmd/templ` directory.
* Tests for the templ runtime are in the root directory.
* Tests for formatting templ files are in `./parser/v2/formattestdata` - it uses txtar to store tests.
* The `htmldiff` library does not take whitespace into account, so cannot be used to test output whitespace handling.
* Don't attempt to run tests individually, use the `xc test` task to run all tests, because it regenerates templates, and there's minimal performance penalty due to Go's test caching.

## Moving and renaming files

* templ files have the `.templ` extension.
* If a `project.templ` file is created, after generation a `project_templ.go` file will be created.
* If a `project.templ` file is renamed, you must also rename the generated `project_templ.go` file.
* If a `project.templ` file is moved, you must also move the generated `project_templ.go` file.
* If a `project.templ` file is deleted, you must also delete the generated `project_templ.go` file.

# Files

* Don't attempt to create helper or utility tests in the `./tmp` or `/tmp` directory. Create unit tests in the relevant directory instead.