Status: early / pre-1.0. treelint is a clean copy of treefmt v2.5.0 that adds first-class linting on top of treefmt's formatter multiplexing, per RFC 0001. The
[linter.<name>]config section, thetreelint checksubcommand, and repair-mode autofixes are implemented. Expect rough edges before 1.0.
treelint runs all your formatters and linters with one command. It inherits treefmt's model: treelint walks the tree, matches files to tools by glob, and runs the matched tools in parallel, only on files that changed since the last run.
The linter additions (RFC 0001):
- A
[linter.<name>]config section parallel to[formatter.<name>]. Itscommandis a read-only check; an optionalrepair-commandapplies autofixes. - First-class repair mode (the default — applies formatter and linter fixes)
and check mode (read-only — reports without writing), exposed via a
treelint checksubcommand. - A sandbox-copy-and-diff strategy so fix-only formatters can be checked without ever writing to your source tree (so checks work even on a read-only tree).
With Nix (the supported path):
nix build github:amarbel-llc/treelint
./result/bin/treelint --help
Or from source with Go ≥ 1.26:
go build -o treelint .
Generate a starter config (writes treelint.toml):
treelint --init
Format the tree (repair mode):
treelint
Check the tree read-only — runs every formatter and linter without writing. Exits 0 when clean, 1 when findings are detected, 2 on an operational error:
treelint check
Print version:
treelint version
Formatters are specified in treelint.toml (or .treelint.toml), discovered by
searching upward from the working directory:
[formatter.nix]
command = "nixfmt"
includes = ["*.nix"]
[formatter.rust]
command = "rustfmt"
options = ["--edition", "2018"]
includes = ["*.rs"]A formatter may declare a native read-only check via check-command /
check-options for use by treelint check; without one, the formatter is
checked through a sandbox copy. Set sandbox = true to force sandbox checking
even when a check command exists.
Linters use a parallel [linter.<name>] section. Its command is the
read-only check (it must exit non-zero on findings); add repair-command /
repair-options to apply autofixes in repair mode. A linter with no
repair-command is a no-op in repair mode:
[linter.shellcheck]
command = "shellcheck"
includes = ["*.sh"]
[linter.ruff]
command = "ruff"
options = ["check"]
repair-command = "ruff"
repair-options = ["check", "--fix"]
includes = ["*.py"]treelint runs tools that follow the formatter specification: files are passed as arguments, the tool writes back only on change, and it exits non-zero on error.
treelint is derived from numtide/treefmt v2.5.0 and is an independent project (not a GitHub fork). treefmt's original copyright and MIT license are retained in LICENSE; see NOTICE for provenance. treelint is released under the MIT license.