Automated Code Formatting with `cljfmt`

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.

Why Automated Formatting Matters

Formatting tools are valuable because they remove low-value discussion from code review:

  • everyone sees the same indentation and spacing rules
  • diffs are smaller and easier to scan
  • editors and CI can enforce the same policy
  • new team members do not need to guess the house style

The real win is not prettier code. It is less friction around code that is already logically correct.

Current Ways To Run cljfmt

The 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.

Fastest Option: Standalone Binary

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.

Clojure CLI Tooling

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.

Leiningen Still Exists, but It Is Not the Default Teaching Model

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.

Configuration Lives in .edn

Modern 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 rules

For most teams, :extra-indents is the safer choice.

Treat Formatting as a Check, Not Just a Fix

The better team workflow is usually:

  1. developers run fix locally
  2. CI runs check
  3. pull requests fail if formatting drift is introduced

That 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.

Editor Integration Is Useful, but Policy Should Not Live Only in the Editor

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:

  • the checked-in config file
  • a documented team command
  • a CI check that prevents drift

That way, formatting still works for teammates using different editors or working through scripts and terminal tools.

Common Mistakes

  • teaching lein-cljfmt as the default for all new projects
  • relying on one editor plugin with no checked-in config
  • treating formatter output as optional suggestion instead of repository policy
  • over-customizing indentation rules until the config becomes harder to understand than the code
  • expecting cljfmt to solve naming, design, or readability problems that are not formatting problems

Key Takeaways

  • cljfmt should be part of the normal development workflow, not an occasional cleanup tool.
  • The current default teaching model should be CLI-first or standalone-binary-first, not Leiningen-only.
  • Keep configuration in .cljfmt.edn or cljfmt.edn.
  • Run fix locally and check in CI.
  • Use formatting to reduce review noise, not to replace judgment about code quality.

References and Further Reading

Ready to Test Your Knowledge?

Loading quiz…
Revised on Thursday, April 23, 2026