The missing formatter and linter for HTML templates.
How to use: English • 简体中文 • 日本語 • Español • Português (Brasil) • Русский • 한국어 • Français • Deutsch • 繁體中文 • Italiano • Polski • Čeština • Türkçe
What lang are you using?
Django • Jinja • Twig • Nunjucks • Handlebars • Mustache • Liquid • Go templates • Angular • Tera • Askama • Mako
🤔 For What?
Every language in your stack has a formatter and a linter, except HTML templates. Generic HTML tools can't parse {% %} and {{ }}, and template engines don't care what the markup around them looks like. So indentation drifts, tags go unclosed and spacing goes wherever, and none of it gets caught in review.
djLint reads HTML and the template syntax inside it, with profiles for Django, Jinja, Twig, Nunjucks, Handlebars, Liquid, Go templates and more.
Take a template only its author could love:
{% block content %}
<SECTION class="posts">
<h2>Latest posts</h2>
{%if posts%}
<ul>
{% for post in posts %}
<li>
<a href="{% url 'post' post.slug %}" class="post-link {%if post.featured%}is-featured{%endif%}" data-analytics-id="post-{{post.id}}" aria-label="Read {{post.title}}">{{post.title|title}}</a>
</li>
{% endfor %}
</ul>
{%else%}
<p>No posts yet.</p>
{%endif%}
</SECTION>
{% endblock %}
One djlint --reformat --single-attribute-per-line later:
{% block content %}
<section class="posts">
<h2>Latest posts</h2>
{% if posts %}
<ul>
{% for post in posts %}
<li>
<a
href="{% url 'post' post.slug %}"
class="post-link {% if post.featured %}is-featured{% endif %}"
data-analytics-id="post-{{ post.id }}"
aria-label="Read {{ post.title }}"
>{{ post.title|title }}</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>No posts yet.</p>
{% endif %}
</section>
{% endblock %}
One command rebuilt the indentation, fixed the tag case, split the long tag into one attribute per line, normalized the template tags and collapsed stray blank lines.
The linter catches what formatting can't fix: orphan tags, missing alt attributes, hard-coded URLs and dozens of other checks.
You can try it on your own templates in the online playground.
✨ How?
Add it to your project as a development dependency with uv
uv add --dev djlint
Or install it as a standalone tool
uv tool install djlint
Or with pip
pip install djlint
Or with pipx
pipx install djlint
Or with the community-maintained Homebrew formula on macOS or Linux
brew install djlint
Or with npm. Warning: the npm package is only a wrapper. Its install script runs pip on whatever python3 is on your system path and installs the djLint version of that npm release, which can replace a newer djLint with an older one. npm will not manage or uninstall the actual package, so prefer pip when you can.
npm i djlint
To run djLint on every commit, see pre-commit.
Lint your project
djlint . --lint
Check your format
djlint . --check --single-attribute-per-line
Fix my format!
djlint . --reformat --single-attribute-per-line
Set a --profile to enable the rules and formatting of your template engine
djlint . --reformat --single-attribute-per-line --profile=django
Or use pre-commit to reformat, then lint!
repos:
- repo: https://github.com/djlint/djLint
rev: v1.49.9 # use the latest version instead
hooks:
- id: djlint-reformat
- id: djlint
🧩 Editors
- VS Code: install the djLint extension (also on Open VSX).
- Neovim, JetBrains IDEs, Sublime Text, Helix and Emacs: run the language server,
djlint --lsp. See the setup for each. - CI: GitHub Actions and MegaLinter.
💙 Like it?
Add a badge to your projects readme.md:
[](https://djlint.com)
Add a badge to your readme.rst:
.. image:: https://img.shields.io/badge/html%20style-djlint-blue.svg
:target: https://djlint.com
Looks like this:
🛠️ Can I help?
Yes!
Would you like to add a rule to the linter? Take a look at the linter docs and the rule definitions.
Local setup takes two commands:
# install uv first: https://docs.astral.sh/uv/getting-started/installation/
uv sync
# run the test suite
uv run pytest
🏃 Other tools of note
- djade A fast Django template formatter that formats template syntax whilst leaving HTML as-is, and applies fixes for older Django versions.
- djangofmt A fast, HTML-aware Django/Jinja template formatter written in Rust that formats HTML and template syntax together.
- DjHTML A pure-Python Django/Jinja template indenter without dependencies.
- prettier-plugin-jinja-template Prettier plugin for formatting Jinja and Django templates.
- prettier-plugin-twig Prettier plugin for formatting Twig templates.
- Twig-CS-Fixer A PHP tool that lints and automatically fixes Twig coding-standard issues.
- ludtwig A fast Rust linter and formatter for Twig templates that also validates HTML structure and supports auto-fix.