Skip to content

Repository files navigation


djLint Logo

The missing formatter and linter for HTML templates.

Downloads Discord

What lang are you using?

DjangoJinjaTwigNunjucksHandlebarsLiquidGo templatesAngularMustacheTeraAskama

🤔 For What?

Every language in your stack has a formatter and a linter. HTML templates are the exception. Generic HTML tools can't parse {% %} and {{ }}, and template engines don't care what the markup around them looks like. Templates end up in a tooling blind spot: drifting indentation, mismatched tags and inconsistent spacing that survive every code review.

djLint covers that blind spot. It understands 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.

And the linter catches what formatting can't fix: orphan tags, missing alt attributes, hard-coded URLs and dozens of other checks.

Try it on your own templates in the online playground →

✨ How?

Grab it from PyPI with pip

pip install djlint

Or as a standalone tool with uv

uv tool 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 install --upgrade djlint on whatever python3 is on your system path. npm will not manage or uninstall the actual package - prefer pip directly when possible.

npm i djlint

Lint your project

djlint . --lint

Check your format

djlint . --check

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.42.1 # use latest version instead
    hooks:
      - id: djlint-reformat
      - id: djlint

🧩 Editors

💙 Like it?

Add a badge to your projects readme.md:

[![Code style: djlint](https://img.shields.io/badge/html%20style-djlint-blue.svg)](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:

djLint

🛠️ 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.

About

✨ HTML Template Linter and Formatter. Django, Jinja, Askama, Tera, Liquid, Nunjucks, Twig, Handlebars, Mustache, GoLang, Angular

Topics

Resources

Stars

Watchers

Forks

Releases

Sponsor this project

Used by

Contributors

Languages