Changelog¶
1.0.0 - 2026-09-20¶
๐ djangofmt 1.0 is here! The formatter is now stable, hardened by extensive fuzzing, ecosystem check and bug fixing. The new
checkcommand also gained automatic Tailwind CSS class sorting, powered by rustywind.
โฐ๏ธ Features¶
- (check) Add
--output-format concise- (4fe930f) - (cli) Add
--target-versionoption (#492) - (eb317d3) - (cli) Add
{# djangofmt: file-ignore[...] #}file-level opt-outs (#440) - (a24f7be) - (cli) Hint at the conditional open/close tag limitation on parse errors (#426) - (7c6c67b)
- (dev) Add cargo-fuzz idempotency fuzzing for the formatter (#435) - (2e0e66e)
- (ecosystem) Report exclusions that are no longer needed (#401) - (0fda5d6)
- (ecosystem) Add EvaP, djangoproject.com, healthchecks, babybuddy, InvenTree and netbox targets (#400) - (969a64c)
- (ecosystem-check) Add 12 Django projects to the corpus (#463) - (788afe8)
- (format) Support
--checkoption for checking formatting without making changes (#496) - (4d92de4) - (format) Accept whitespace around
:in the ignore directive (#449) - (4f149a2) - (lint) Stabilize the linter for 1.0 (#517) - (49e56ed)
- (lint) Add a
pedanticcategory and leave it out of the default rule set (#508) - (6a7ead9) - (lint) Add
unused-ignore-codelint rule (#487) - (486e2d6) - (lint) Add
deprecated-ignorelint rule (#443) - (59b2d58) - (lint) Infer
target-versionfrom thedjangorequirement (#495) - (95b98e6) - (lint) Add
invalid-ignore-commentandinvalid-ignore-codelint rules (#442) - (6e8f422) - (lint) Suppress diagnostics with
{# djangofmt: ignore[rule] #}comments (#441) - (ef3335f) - (lint) Honor rule codes in
{# djangofmt: file-ignore[...] #}(#470) - (a4aea6d) - (lint) Add
unsorted-tailwind-classeslint rule (#332) - (da2a7aa) - (lint) Add
same-file-partial-includelint rule (#344) - (a103419) - (lint) Add
per-file-ignoresconfiguration (#411) - (fefdd9b)
๐ Bug Fixes¶
- (check) Render parse errors concisely with
--output-format concise(#394) - (b821e10) - (ci) Actually truncate the ecosystem comment body - (58bbd22)
- (cli) Stop breaking help URLs across lines (#458) - (63af806)
- (cli) Honor a leading
djangofmt:ignoreon unparsable files incheck(#439) - (8974a3b) - (cli) Anchor include and exclude patterns at the project root (#433) - (2e98311)
- (cli) Report accurate parse error locations (#430) - (de1ddde)
- (cli) Exit 2 on I/O and parse errors in file mode (#429) - (34f5745)
- (format) Reject self-closing non-void HTML elements as a parse error (#516) - (2e90033)
- (format) Keep a comment-only CSS block instead of emptying it (#499) - (f39c760)
- (format) Keep
/*!,/*#and/**CSS comment markers intact (#498) - (25c46f7) - (format) Leave JSON with raw control characters in strings unformatted (#485) - (69edc82)
- (format) Stop reordering CSS shorthands past the longhands they override (#483) - (c77d667)
- (format) Respect internal attr loop separator (#480) - (11aee2f)
- (format) Honor
{# djangofmt: ignore[format] #}on the next node (#473) - (e4ea817) - (format) Reject malformed template syntax instead of silently corrupting it (#457) - (04e8d72)
- (format) Recover from panics instead of crashing the whole run (#459) - (5c3837b)
- (format) Keep the opening tag of an ignored nested block tag (#434) - (4a56d53)
- (format) Resolve stdin profile with the same precedence as files (#413) - (78bed0d)
- (format) Don't treat
---as front matter outside the top of the file (#407) - (d41752d) - (format) Only treat Django's built-in tags as block tags (#402) - (275acaa)
- (format) Re-indent
{% endcomment %}with its block (#395) - (6612b1b) - (format) Don't panic on
{% comment %}among tag attributes (#393) - (9522c6e) - (lint) More small linter fixes and perf improvements (#521) - (efd6d4d)
- (lint) Minor lint rule fixes (#520) - (fc3eec9)
- (lint) Detect whitespace-padded URLs in django-static-url and django-url-pattern (#431) - (7de1dd7)
- (lint) Don't disable missing-doctype on root-level Jinja blocks (#427) - (b74d4d4)
- (lint) Restore build for
form-action-whitespacefix content (#399) - (1ec0946) - (playground) Fix border of plus/minus inputs (#382) - (c026381)
- (release) Opt the binary back into
distafterpublish = false(#509) - (2735037)
๐ Refactor¶
- (cli) Count check results in a single pass (#468) - (06e3aa5)
- (cli) Unify parsing into a
lint_sourceandparse_sourceinterface (#404) - (017e23e) - (dev) Move generated-page prose out of Rust into Markdown files (#437) - (1781144)
- (ecosystem) Document ecosystem exclusion reasons (#410) - (96f070c)
- (format) Delete dead display only fix api (#414) - (2e5b7d2)
- (lint) Pass checker as the first argument to rule check functions (#505) - (5678cbb)
- (lint) Route
check,--fixand the playground through onelint_textapi (#490) - (6c8d3e9) - (lint) Add
source_span/source_endhelpers and derive spans from slices (#484) - (35653ce) - (lint) Tighten diagnostic messages and help text (#481) - (253e26f)
- (lint) Parse suppression directives with one shared grammar (#472) - (e8a5667)
๐ Documentation¶
- (agents) Sync the add-lint-rule skill and AGENTS.md with the current code - (0226c88)
- (benchmark) Update benchmark numbers (#454) - (c725574)
- (format) Document the omitted end tag limitation and link the hint to it (#515) - (7d00e1a)
- (skill) Insist rule doc comments say what, never how (#424) - (2b6a243)
- Document LF-only output as a known limitation (#461) - (de59f2b)
โก Performance¶
- (bench) Add a reporter benchmark covering diagnostic rendering (#390) - (70c2820)
- (format) Use
oxc-miettefor ~5x faster diagnostic rendering (#392) - (822a21f) - (lint) Avoid allocating for static violation messages, help and fix titles (#397) - (e67ab92)
- (lint) Avoid allocating for static fix content (#398) - (72551cc)
- (lint) Use &'static str for diagnostic rule codes (#396) - (be7ed4f)
๐งช Testing¶
- (bench) Benchmark the default rule selection, not just none and all (#412) - (b9e9591)
- (benchmark) Benchmark templates carrying a
djangofmt:directive (#469) - (00c4553) - (ecosystem) Drop the stale bookwyrm
manual-merge.htmlexclusion (#497) - (9be0f74) - (ecosystem) Exclude django-unfold
avatar.html(dynamic tag name) (#455) - (30ba2c8) - (ecosystem) Update ecosystem exclusion list and also check stability false positives (#403) - (671704f)
- (ecosystem-check) Report fixable lint changes as a source diff - (cfa4d66)
- (format) Pin lowercased CSS property names as intended (#486) - (60d599d)
- (fuzz) Skip control-character inputs in the idempotency target (#504) - (1f0b3df)
- (refactor) Drop tests already covered elsewhere (#438) - (e5b827f)
- (refactor) Each rule test fixture now only enable the rule (#406) - (d0921df)
โ๏ธ Miscellaneous Tasks¶
- (benchmark) Fix codspeed flakiness after v5 (#448) - (2dfa651)
- (changelog) Add a one-off 1.0 banner to the generated changelog (#464) - (d4994ef)
- (ecosystem) Add a parse check that fails when formatting breaks templates (#494) - (43a6507)
- (ecosystem) Stop rebuilding
djangofmta third time in the ecosystem check (#456) - (43fd237) - (release) Fix s390x cross build of psm assembly (#453) - (0d8e8de)
- (security) Reject a tampered
pr-numberartifact before it reachesGITHUB_OUTPUT(#514) - (21a11e0) - (security) Harden release workflow permissions, inputs, and caching (#422) - (4df167d)
- (stability) Reduce codspeed variance (#465) - (657918f)
- (tests) Regenerate snapshots in insta's current format (#475) - (23cca63)
- Pin cargo dev tools through uv.lock (#477) - (f92f89c)
- Drop the cargo-bloat workflow for a just recipe (#479) - (110c8a2)
- Build and test with --locked (#476) - (7a87cea)
- Set UV_LOCKED in workflows that resolve dependencies (#478) - (81e72fd)
New Contributors โค๏ธ¶
0.2.12 - 2026-07-15¶
โฐ๏ธ Features¶
๐ Bug Fixes¶
0.2.11 - 2026-06-26¶
โฐ๏ธ Features¶
- (format) Preserve single-line Django blocks inside attribute lists (#360) - (ca3d825)
- (format) Support
.editorconfigconfiguration files (#349) - (0df2c71) - (lint) Add duplicate-block-name lint rule - (4fe9aef)
- (lint) Add rule selection (select/ignore + preview) (#350) - (7d0eb76)
- (playground) Add documentation link to navbar (#351) - (0923257)
๐ Bug Fixes¶
- (format) Fix formatting of multiline django template tags (#359) - (2908461)
- (lint) Restore correct ANSI display in error messages (#346) - (d4c21ba)
๐ Refactor¶
- (lint) Avoid double parse when fixing (#362) - (621980e)
- (lint) Drop redundant help on empty-attr-value rule (#357) - (e10ed1e)
- (lint) Cleanup RuleSet implementation and simplify (#336) - (17c0668)
- (misc) Minor cleanup (#356) - (2b1346b)
- (tests) Misc test simplification (#348) - (cdda76a)
๐งช Testing¶
- (bench) Isolate check_ast cost from parsing (#364) - (8251c11)
- (clippy) Enable more clippy restriction rules (#363) - (539450c)
- (ecosystem-check) Select all rules + preview in check ecosystem run (#352) - (17110ef)
โ๏ธ Miscellaneous Tasks¶
0.2.10 - 2026-06-03¶
โฐ๏ธ Features¶
- (format) Allow
{# djangofmt:ignore #}to disable formatting (#333) - (8de13fc) - (lint) Add
django-url-patternlint rule (#314) - (9cfc71c) - (lint) Add
empty-tag-pairlint rule (#313) - (5ac93df) - (lint) Add
missing-img-altlint rule (#312) - (d7e3d38) - (lint) Add
django-static-urllint rule (#311) - (27836b6) - (lint) Add
use-httpslint rule (#308) - (3503bc7) - (playground) Add ast + Doc IR representation in playground (#331) - (c9489bb)
๐ Bug Fixes¶
๐ Refactor¶
- (lint) Dispatch per-attribute rules from a single attribute visitor (#330) - (d02925c)
- (lint) Dispatch tag-scoped rules by tag (#326) - (4c1a059)
- (lint) Check img height and width attributes in a single pass (#322) - (5164cea)
- (lint) Reuse fs::get_cwd and drop build_walk_filters wrapper (#320) - (9aab7b7)
- (lint) Add
fix::editsmodule withdelete_attr_fixhelper (#319) - (d7cc9ad) - (lint) Extract jinja-aware attr-presence helper (#318) - (6910bd9)
- (lint) Fold attribute value match into NativeAttribute pattern (#317) - (67f5802)
- (playground) Switch to deno (#316) - (2abd19d)
- (test) Share benchmark template list via
ALL_TEMPLATESconst (#321) - (2eab77b)
โก Performance¶
- (format) Update
markup_fmtleading to average perf improvement of 2x (#329) - (d0329ca) - (lint) Use a BitSet to store enabled rules (#325) - (347d0b9)
0.2.9 - 2026-05-29¶
โฐ๏ธ Features¶
- (check) Expose --fix, --unsafe-fixes, --show-fixes in pyproject config (#290) - (448f487)
- (docs) Publish Zensical-based documentation site (#300) - (5f29df3)
- (lint) Add
missing-doctypelint rule (#310) - (e372374) - (lint) Add
missing-titlelint rule (#309) - (b243792) - (lint) Add
duplicate-attrlint rule (#304) - (ef732af) - (lint) Add
form-action-whitespacelint rule (#303) - (c2b3d53) - (lint) Add
empty-attr-valuelint rule (#298) - (559313c) - (lint) Add
uppercase-form-methodlint rule (#294) - (4d37afe) - (lint) Add
javascript-urllint rule (#293) - (791e928) - (lint) Add
redundant-type-attrrule (#260) - (3d65c26)
๐ Refactor¶
๐ Documentation¶
- (lint) Auto-generate lint rule docs from violation struct doc comments (#297) - (3670b71)
- (pycharm) Pycharm editor integration (#301) - (bbf6823)
- (readme) Extract some part of the README to dedicated doc page (#291) - (1ea7bae)
โ๏ธ Miscellaneous Tasks¶
- (pre-commit) Chore/pre commit autoupdate and zizmor (#299) - (2dd2c0e)
- Scope pages concurrency per PR (#315) - (57ae947)
0.2.8 - 2026-05-18¶
โฐ๏ธ Features¶
- (check) Add autofix framework to the
djangofmt checkcommand and theblocktranslate-no-trimmedrule (#276) - (0b04439) - (cli) Format from stdin via
-or--stdin-filename(#284) - (a876757) - (format) Add
--preserve-unquoted-attrsoption (#271) - (081ab4a) - (format) Add support for Django template partials (#275) - (a13115e)
๐ Bug Fixes¶
โ๏ธ Miscellaneous Tasks¶
- (msrv) Track MSRV and rust-toolchain version with renovate (#281) - (690170f)
- (perf) Include all rust-related files in changed_files detection (#280) - (f182cfa)
- (renovate) Add 7-day cooldown to mitigate supply chain attacks (#266) - (ce3759f)
- Set CARGO_PROFILE_DEV_DEBUG=line-tables-only for faster builds (#270) - (06486be)
Build¶
New Contributors โค๏ธ¶
- @nickpetrovic made their first contribution in #271
- @meshy made their first contribution in #267
0.2.7 - 2026-04-16¶
โฐ๏ธ Features¶
- (ci) Build pipeline improvements (#225) - (3e3b009)
- (config) Use kebab-case for pyproject.toml settings (#227) - (f26e834)
- (format) Add recursive file discovery -- enable
djangofmt .to format the current folder (#229) - (385f60a) - (format) Add flag to allow self closing void elements (#219) - (d0d85b0)
- (format) Improve error message for cut off html (#207) - (decbaec)
- (format) Add JSON external formatter (#188) - (07e770b)
๐ Bug Fixes¶
- (format) Fixes extra indent for {% plural %} inside blocktranslate (#208) - (c7de06d)
- (format) Fix formatting issues for nested template blocks in html opening tag (#205) - (378bc36)
๐ Refactor¶
- (format) Reuse
LineLengthandPrintWidthnewtypes to remove hardcoded default values (#189) - (13e89b5) - (misc) Avoid clone on check error path, add force_exclude tests (#239) - (abc267d)
- (misc) Hoist Settings::default(), remove dead Hash derive, avoid clone on error path (#237) - (2923267)
- (misc) Minor code quality improvement and simplifications (#235) - (1c1c856)
- (rules) Declare lint rule category on the Violation (#230) - (6dd81ab)
๐ Documentation¶
- (ai) Add AI policy to CONTRIBUTING.md (#228) - (479c575)
- (check) Document check mode workaround (#200) - (8be5ca6)
โก Performance¶
- (bench) Bench linter and parser (#232) - (d1644eb)
- (summary) Add micro bench build summary (#236) - (6ba6a80)
๐งช Testing¶
- (ci) Add
djangofmt checkto ecosystem check (#253) - (e9ac547) - (ci) Add code coverage with cargo-llvm-cov and 85% CI threshold (#240) - (78a97a6)
- (ci) Re-enable djade ecosystem check (+ tidy up justfile) (#206) - (461db3b)
- (ci) Remove docker-run-action (#195) - (c1c080b)
- (ecosystem-check) Allows pr comment on forks (#196) - (54b204d)
- (lint) Cleanup lint test structure (#254) - (5bf935e)
โ๏ธ Miscellaneous Tasks¶
New Contributors โค๏ธ¶
- @jonathan-s made their first contribution in #200
0.2.6 - 2026-02-10¶
โฐ๏ธ Features¶
๐ Bug Fixes¶
- (format) Always swap wrapping quotes if attribute contains one (#180) - (0fd9ed3)
- (format) Fix formatting of
{% for %}/{% empty %}blocks (#178) - (98f8ef7)
๐ Documentation¶
- (format) Documents workarounds for unsupported formatting (#174) - (15b1f32)
- (github) Add Github issue template (#173) - (5821c07)
- (ignore) Document ignore comment (#172) - (50a2fdd)
๐งช Testing¶
0.2.5 - 2026-01-12¶
โฐ๏ธ Features¶
- (debug) Add debug logs on external formatter failures (#143) - (a5dda3b)
- (format) Don't format django multiline comment tags (
{% comment %}...{% endcomment %}) (#162) - (6a6ca10) - (format) Auto-sort css statements using
smacssordering and enforce%in keyframes (#114) - (1dd641f) - (format) Auto-indent
<script>tag content (#115) - (d959cf0) - (format) Keep style attribute value on a single line (#113) - (7c2f33c)
- (format) Skip file parsing if there is a top-level
<!-- djangofmt:ignore -->(#112) - (fcbab9b) - (format) Improve formatting of
styletags and attributes (#111) - (24920db) - (lint) Show source file name in lint diagnostics (#159) - (6ee8c96)
- (lint) Add building blocks for linting (#144) - (08a12a0)
- (playground) Add a "Open issue on Github" button in the playground (#163) - (ae247b3)
- (playground) Add a new collapsible panel to display linting errors (#148) - (067e4a0)
- (playground) Add playground deploy to release workflow (#124) - (124b149)
- (playground) Add an online playground (#118) - (a655190)
- (playground) Expose a wasm format command (#122) - (847d3d8)
๐ Bug Fixes¶
๐ Refactor¶
- (cargo) Switch to workspace setup (#121) - (ad75960)
- (format) Remove
line_col_to_offsetand use mietteSourceOffset::from_locationfor error reporting (#145) - (f8acc95)
โก Performance¶
- (allocator) Use jemalloc on linux (#128) - (4e92927)
- (codspeed) Setup Codspeed CI benchmarks (#125) - (0ea2b39)
- (perf) Update the
ltoandcodegen-unitsbenchmark script (#126) - (ccd7ede)
๐งช Testing¶
- (binary-size) Add cargo-bloat (#136) - (2855cb2)
- (ci) Skip codspeed in CI if no rust code changes (#158) - (8bf4432)
- (ci) Cancel outdated ci jobs - (18595c3)
- (clippy) Improve clippy configuration (#156) - (2de17b3)
- (pre-commit) Switch to a managed
dprintpre-commit integration (#138) - (1ccfba0) - (pre-commit) Simplify dprint discovery in pre-commit (#137) - (f4eb28c)
- (review) Add coderrabit (#141) - (bac6128)
โ๏ธ Miscellaneous Tasks¶
New Contributors โค๏ธ¶
0.2.3 - 2025-11-30¶
โฐ๏ธ Features¶
- (format) Add pretty-printing of parse errors (#104) - (fee4ee3)
- (format) Add custom
<!-- djangofmt:ignore -->directive (#102) - (c9b20bb) - (format) Improvements on inline node formatting (#75) - (58a4f8f)
๐ Refactor¶
๐งช Testing¶
- (clippy) Enable strict clippy rules (#97) - (cd7d6ea)
- (ecosystem-check) Fix ecosystem check comment urls and support codeberg.com (#101) - (337592c)
- (ecosystem-check) Fix ecosystem-check and support other providers than github (#99) - (13e8bb2)
0.2.2 - 2025-06-12¶
โฐ๏ธ Features¶
- (format) Document svg files support (#74) - (60ba20f)
- (format) Support unquoted attr value recovery for jinja tags & blocks (#73) - (ca7efc6)
0.2.1 - 2025-06-07¶
โฐ๏ธ Features¶
0.2.0 - 2025-05-23¶
โฐ๏ธ Features¶
- (cli) Add
indent_widthcli parameter (#48) - (b0d0219) - (fmt) Never wrap opening tag with no attrs (#20) - (8fb993a)
- (format) Converge in one pass formatting style attr (#50) - (fadce6b)
๐ Bug Fixes¶
- (cli) Exit
1on handled formatting failure - (b7ebb78)
๐งช Testing¶
- (ecosystem-check) Stability test + Integration test with djade (#51) - (449456e)
- (pre-commit.ci) Enable
pre-commit.ci(#15) - (5ce836f)
โ๏ธ Miscellaneous Tasks¶
- (markup_fmt) Bump
markup_fmtto v0.20.0 (#65) - (070e2af) - (rust) Rust 1.87 edition 2024 (#55) - (9aeb174)
New Contributors โค๏ธ¶
- @renovate[bot] made their first contribution in #64
- @pre-commit-ci[bot] made their first contribution in #52
0.1.0 - 2025-03-16¶
New Contributors โค๏ธ¶
- @UnknownPlatypus made their first contribution