cmakefmt
A blazing-fast, workflow-first CMake formatter — built in Rust, built to last.
cmakefmt was born from frustration with cmake-format, the beloved-but-aging
Python tool from the cmakelang project. Instead of patching around its limits,
cmakefmt starts from scratch: a native Rust binary that respects your time,
your CI budget, and your build system.
Same spirit. No Python. No compromises.
Crates.io package name: cmakefmt-rust (CLI binary remains cmakefmt).
This project is independent from other Rust implementations, including
azais-corentin/cmakefmt and yamadapc/cmakefmt.
Why cmakefmt?
- 20× faster — not a typo.
cmakefmthits a20.69xgeometric-mean speedup overcmake-formaton real-world CMake corpora. Pre-commit hooks that once made you wince now finish before you blink. - Zero dependencies. One binary. No Python environment, no virtualenv bootstrap, no “works on my machine” dependency drift. Drop it in CI and forget about it.
- Built for actual workflows.
--check,--diff,--staged,--changed,--files-from,--show-config,--explain-config, JSON reporting — the power-user features thatcmake-formatmade you script around are all first- class citizens here. - Knows your commands. Teach
cmakefmtabout your project’s custom CMake functions and macros. No more generic token wrapping for functions you wrote. - Errors that actually help. Parse and config failures come with file/line context, source snippets, and reproduction hints — not a wall of opaque parser noise.
- Designed for real repositories. Comment preservation, disabled regions, config discovery, ignore files, Git-aware file selection, and opt-in parallelism are core features, not afterthoughts.
Performance Snapshot
The numbers speak for themselves:
| Metric | Signal |
|---|---|
Geometric-mean speedup vs cmake-format | 20.69x |
End-to-end format_source, large synthetic input (1000+ lines) | estimate 8.8248 ms (95% CI 8.8018–8.8519 ms) |
| Parser-only, large synthetic input | estimate 7.1067 ms (95% CI 7.0793–7.1359 ms) |
| Serial whole-corpus batch (220 files) | 184.5 ms ± 1.3 ms |
--parallel 8 whole-corpus batch | 48.5 ms ± 1.5 ms |
95% CI is the Criterion-reported confidence interval: the range within which the true mean is expected to fall 95% of the time.
Fast enough for local dev, pre-commit hooks, editor integrations, and CI — all at once. The only question is: why settle for slower?
Curious about methodology? Evaluating whether it’s worth switching?
Read Performance and Migration From cmake-format.
Quick Start
Install from this repository:
cargo install --path .
Dump a starter config:
cmakefmt --dump-config > .cmakefmt.yaml
Check your entire repository without touching a single file:
cmakefmt --check .
Rewrite everything in place:
cmakefmt --in-place .
Format only the CMake files you’re about to commit:
cmakefmt --staged --check
What cmakefmt Covers Today
- recursive discovery of
CMakeLists.txt,*.cmake, and*.cmake.in - in-place formatting, stdout formatting,
--check,--diff, and JSON reports - YAML or TOML config files, with YAML preferred for larger user configs
- custom command specs and per-command formatting overrides
- comment preservation, fence/barrier passthrough, and markup-aware handling
- config introspection with
--show-config,--show-config-path, and--explain-config - Git-aware workflows:
--staged,--changed, and--since - rich debug output for discovery, config resolution, barriers, command forms, and layout choices
- opt-in parallel execution for multi-file runs
- a built-in command registry audited through CMake
4.3.1
Suggested Reading Order
New here?
Migrating from cmake-format?
Embedding cmakefmt as a library?
Common Workflows
Preview which files would change before touching anything:
cmakefmt --list-changed-files .
See the exact patch instead of applying it:
cmakefmt --diff CMakeLists.txt
Trace which config file a target will actually use:
cmakefmt --show-config-path src/CMakeLists.txt
Inspect the fully resolved, effective config:
cmakefmt --show-config src/CMakeLists.txt
Current Status
cmakefmt is pre-1.0 — honest about it, but already genuinely useful. Active
development is focused on:
- polishing documentation and the onboarding experience
- tightening release and distribution channels
- staying well ahead of
cmake-formaton performance and workflow ergonomics
Hit something unexpected? Start with Troubleshooting, then
reach for --debug and --explain-config before filing a bug report.