A fast, HTML aware, Django template formatter, written in Rust.
Formatting 100k+ lines of HTML across 1.7k+ files from scratch.
Heavily rely on the awesome markup_fmt with some additions to support Django fully.
- Installation
- Usage
- Pre-commit hook
- Configuration
- Editor integration
- Controlling the formatting
- Known limitations
- Benchmarks
- Shell completions
- Contributing
djangofmt is available on PyPI.
# With pip
pip install djangofmt
# With uv
uv tool install djangofmt@latest # Install djangofmt globally.
uv add --dev djangofmt # Or add djangofmt to your project.
# With pipx
pipx install djangofmtdjangofmt . # Format all files in the current directory (and any subdirectories).
djangofmt src/templates # Format all template files in `src/templates`
djangofmt templates/base.html # Format individual filesWhen given a directory, djangofmt recurses into it and formats all *.html, *.jinja, *.jinja2, and *.j2 files it finds.
It also respects .gitignore files.
djangofmt intentionally does not provide a built-in check functionality because CI is too late for a code formatter. We strongly recommend using pre-commit or any IDE "format on save" integration. That being said, you can emulate check capability by chaining with a git diff command like so:
djangofmt .
git diff --exit-code -- '*.html' || (echo "HTML templates are not formatted. Run 'djangofmt' to fix." && exit 1)See pre-commit for instructions.
Sample .pre-commit-config.yaml:
- repo: https://github.com/UnknownPlatypus/djangofmt-pre-commit
rev: v0.2.8
hooks:
- id: djangofmtThe separate repository enables installation without compiling the Rust code.
By default, the configuration uses pre-commit's files option to detect
all text files in directories named templates. If your templates are stored elsewhere, you can override this behavior
by specifying the desired files in the hook configuration within your .pre-commit-config.yaml file.
djangofmt can format svg files too. It will behave exactly the same way as if they were html files. There is a dedicated pre-commit hook for these:
- repo: https://github.com/UnknownPlatypus/djangofmt-pre-commit
rev: v0.2.8
hooks:
- id: djangofmt-svgDjangofmt can also be configured via a [tool.djangofmt] section in your pyproject.toml:
[tool.djangofmt]
line-length = 120
indent-width = 4
profile = "django"
custom-blocks = ["stage", "flatblock"]
html-void-self-closing = "never"
preserve-unquoted-attrs = falseDjangofmt looks for a pyproject.toml file by traversing directories upward from the current working directory.
The first pyproject.toml found is used. If no file is found or the file doesn't contain a [tool.djangofmt] section, defaults are used.
Command-line arguments always take precedence over pyproject.toml settings.
See Controlling the formatting for the behaviour of each option and how to opt into per-node overrides.
See docs/editor-integration.md.
You can generate shell completions for your preferred
shell using the djangofmt completions command.
Usage: djangofmt completions <SHELL>
Arguments:
<SHELL>
The shell to generate the completions for
[possible values: bash, elvish, fish, nushell, powershell, zsh]Contributions are welcome! Please see CONTRIBUTING.md for details on how to get started.