| name | nix-treefmt-formatter |
| description | treefmt-nix formatter for Nix flakes — `formatter.nix` via `treefmt-nix.lib.evalModule` (build.wrapper + build.check), lint→format ordering with priorities (deadnix→nixfmt, shellcheck→shfmt, ruff-check→ruff-format), and the format check wired into `nix flake check` via passthru.tests. Apply when writing or editing formatter.nix / treefmt config in a flake; when adding a language formatter (Go, Python, shell, YAML, TOML, Markdown, just); when `nix fmt` misbehaves, formats vendored files, or skips files (excludes, on-unmatched, default excludes); when CI passes `nix flake check` but formatting is actually broken (check never ran); when deadnix deletes wanted lambda args. Do NOT use for non-treefmt formatting setups, editor/IDE format-on-save config, or choosing code style rules of a language. |
| user-invocable | true |
| license | MIT |
| compatibility | Designed for Claude Code, Codex or similar harness, and for Nix flakes using treefmt-nix (with or without numtide/blueprint). |
| metadata | {"author":"aldoborrero","version":"1.1.0","openclaw":{"emoji":"🧹","homepage":"https://github.com/aldoborrero/cc-skills-nix","requires":{"bins":"[Truncated]"},"install":[]}} |
| allowed-tools | Read Edit Write Glob Grep Bash(nix:*) Bash(git:*) Agent |
| paths | ["**/formatter.nix","**/treefmt.nix","**/treefmt.toml","**/flake.nix"] |
treefmt-nix formatter with a CI-enforced check
One formatter.nix gives you nix fmt (format everything) and a format check that makes nix flake check fail on unformatted code. Requires inputs.treefmt-nix (with inputs.nixpkgs.follows = "nixpkgs").
In a blueprint repo, the file lives at <prefix>/formatter.nix and is auto-wired: it becomes the flake formatter output and the package formatter, whose passthru.tests land in checks.<sys>.pkgs-formatter-*. Without blueprint, export build.wrapper as formatter.<sys> and build.check under checks yourself.
The template (verified end to end: red on a dirty tree, green after nix fmt)
{ flake, inputs, pkgs, ... }:
let
mod = inputs.treefmt-nix.lib.evalModule pkgs {
projectRootFile = "flake.nix";
programs = {
# nix — deadnix strips dead code, then nixfmt formats
deadnix.enable = true;
deadnix.no-lambda-pattern-names = true; # don't break callPackage-style { pkg1, pkg2, ... } patterns
deadnix.priority = 1;
nixfmt.enable = true;
nixfmt.priority = 2;
# add per-language blocks here (see reference)
};
};
wrapper = mod.config.build.wrapper;
in
wrapper // { passthru = wrapper.passthru // { tests.check = mod.config.build.check flake; }; }
build.check is treefmt-nix's own check derivation (function: source tree → package): it copies the tree, git init && git add && git commit, runs treefmt, and fails printing the diff if git detects changes. Hermetic, so one nix flake check covers builds, tests and formatting in a single CI job. Older repos hand-roll the same thing as a pkgs.runCommand copying ${flake} — equivalent, just more code to maintain.
treefmt-nix.lib.mkWrapper pkgs settings is the wrapper-only shorthand; use evalModule when you also want build.check (or build.configFile) from one evaluation.
THE bug to check first: passthru.tests, not meta.tests
Blueprint (and nixpkgs convention) collects package tests from passthru.tests only. A formatter ending in
formatter // { meta = formatter.meta // { tests = { check = check; }; }; } # WRONG