How to use `cljfmt` in modern Clojure projects, with CLI-first workflows, configuration files, and team-friendly formatting policy.
cljfmt is a formatter for Clojure code. Its job is not to redesign your program, but to detect and fix formatting inconsistencies so the team stops spending attention on indentation, whitespace, and line wrapping during review.
For modern Clojure projects, formatting should be treated as a workflow default, not as a cleanup step someone remembers at the end of the week.
Formatting tools are valuable because they remove low-value discussion from code review:
The real win is not prettier code. It is less friction around code that is already logically correct.
cljfmtThe cljfmt README now documents several ways to use it. The important point is that new examples should not assume a Leiningen plugin as the only default.
If you want the simplest developer experience, the standalone binary is often the easiest path:
1cljfmt check
2cljfmt fix
That works well for local developer machines, pre-commit hooks, and editor integration.
In a current Clojure CLI workflow, installing cljfmt as a tool is a strong default:
1clj -Ttools install io.github.weavejester/cljfmt '{:git/tag "0.16.3"}' :as cljfmt
Then run:
1clj -Tcljfmt check
2clj -Tcljfmt fix
This keeps formatting available without turning every project into a formatter-installation exercise.
If a legacy codebase still uses Leiningen, lein-cljfmt is still a valid inherited setup:
1:plugins [[dev.weavejester/lein-cljfmt "0.16.3"]]
Then:
1lein cljfmt check
2lein cljfmt fix
That is fine for established projects. The main rule is not to teach Leiningen-first workflow as if it were the only current way to use the tool.
.ednModern cljfmt expects configuration in .edn files such as .cljfmt.edn or cljfmt.edn.
1{:remove-trailing-whitespace? true
2 :remove-consecutive-blank-lines? true
3 :insert-missing-whitespace? true
4 :extra-indents {compojure.core/GET [[:inner 0]]}}
This is where teams should put project-specific indentation rules, not inside scattered editor notes or tribal knowledge.
One subtle but important current detail from the README is that newer versions distinguish between:
:indents, which replaces the default indent map:extra-indents, which extends the default rulesFor most teams, :extra-indents is the safer choice.
The better team workflow is usually:
fix locallycheckThat keeps CI deterministic without silently rewriting code in the pipeline.
flowchart LR
A["Edit code"] --> B["Run cljfmt fix locally"]
B --> C["Commit formatted files"]
C --> D["CI runs cljfmt check"]
D --> E{"Formatting clean?"}
E -- Yes --> F["Review and merge"]
E -- No --> G["Fix formatting and rerun"]
This is the better mental model: auto-fix locally, enforce in CI.
Many editors can run cljfmt on save, which is helpful. But do not let the editor become the only place where formatting rules exist.
The durable source of truth should be:
That way, formatting still works for teammates using different editors or working through scripts and terminal tools.
lein-cljfmt as the default for all new projectscljfmt to solve naming, design, or readability problems that are not formatting problemscljfmt should be part of the normal development workflow, not an occasional cleanup tool..cljfmt.edn or cljfmt.edn.fix locally and check in CI.