one CLI to format your repo (Go re-write)
This repository has been archived on 2024-05-03. You can view files and clone it, but cannot push or open issues or pull requests.
Go to file
Brian McGee ea6fe2d5cb
doc: improve treefmt.gif
Add some whitespace to each file in the examples folder before applying to demonstrate formatting occurring.

Signed-off-by: Brian McGee <>
2024-05-03 20:04:13 +01:00
.github ci: remove henri 2024-05-03 18:16:24 +01:00
build feat: support --version 2024-02-15 13:59:56 +00:00
cache fix: fmt.Errorf formats 2024-05-02 11:40:49 +01:00
cli fix: fmt.Errorf formats 2024-05-02 11:40:49 +01:00
config feat: refactor some config init logic into config package 2024-05-02 10:56:32 +01:00
docs doc: improve treefmt.gif 2024-05-03 20:04:13 +01:00
format fix: fmt.Errorf formats 2024-05-02 11:40:49 +01:00
nix fix: vhs command wrapper 2024-05-03 20:03:40 +01:00
stats feat: add stats output similar to 2024-05-01 11:23:55 +01:00
test fix: record cache entries for files that don't match formatters 2024-05-02 08:58:02 +01:00
walk fix: fmt.Errorf formats 2024-05-02 11:40:49 +01:00
.envrc feat: add nix direnv source to .envrc 2024-02-14 15:15:39 +00:00
.gitignore doc: move assets into public folder 2024-05-02 11:41:37 +01:00
default.nix feat: add flake compat 2024-05-02 11:41:39 +01:00
flake.lock chore: remove flake-root input 2024-05-02 13:41:10 +01:00
flake.nix doc: change project url to 2024-05-03 13:30:40 +01:00
go.mod feat: upgrade modules 2024-05-03 13:35:30 +01:00
go.sum feat: upgrade modules 2024-05-03 13:35:30 +01:00
gomod2nix.toml feat: upgrade modules 2024-05-03 13:35:30 +01:00
init.toml feat: implement init 2024-02-28 09:18:45 +00:00 doc: update licence copyright year 2024-02-15 14:00:47 +00:00
main.go chore: refactor logging initialisation 2024-05-02 10:31:25 +01:00 fix: rename treefmt.go to treefmt-go 2024-05-03 16:30:24 +01:00
shell.nix feat: add flake compat 2024-05-02 11:41:39 +01:00

treefmt — one CLI to format your repo

Support room on Matrix

Status: beta

treefmt streamlines the process of applying formatters to your project, making it a breeze with just one command line.


Its common to format code according to the projects standards before making contributions to any project. This task seems trivial at first sight — you can set up the required language formatter in your IDE.

However, contributing to multiple projects requires more effort: you must change your formatter configurations each time you switch between projects or call them manually.

Formatting requires less effort if a universal formatter for multiple languages, which is also project-specific, is in place.

About treefmt

treefmt runs all your formatters with one command. Its easy to configure and fast to execute.

Treefmt Init

Its main features are:

  • Providing a unified CLI and output
    • You dont need to remember which formatters are necessary for each project.
    • Once you specify the formatters in the config file, you can trigger all of them with one command and get a standardized output.
  • Running all the formatters in parallel
    • A standard script loops over your folders and runs each formatter sequentially.
    • In contrast, treefmt runs formatters in parallel. This way, the formatting job takes less time.
  • Tracking file changes
    • When formatters are run in a script, they process all the files they encounter, regardless of whether or not they have changed.
    • treefmt tracks file changes, and only attempts to format files which have changed.

To reformat the whole source tree, just type treefmt in any folder. This is a fast and simple formatting solution.


You can install treefmt by downloading the binary. Find the binaries for different architectures here. Otherwise, you can install the package from source code — either with Go, or with the help of nix.

We describe the installation process in detail in the docs.


In order to use treefmt in your project, make sure the config file treefmt.toml is present in the root folder and is edited to suit your needs.

You can generate it with:

$ treefmt --init

You can then run treefmt in your project root folder like this:

$ treefmt

To explore the tools flags and options, type:

$ treefmt --help

Additionally, there's a wrapper called treefmt-nix for using treefmt with nix.


Formatters are specified in the config file treefmt.toml, which is usually located in the project root folder. The generic way to specify a formatter is like this:

command = "<formatter-command>"
options = ["<formatter-option-1>"...]
includes = ["<glob>"]

For example, if you want to use nixpkgs-fmt on your Nix project and rustfmt on your Rust project, then treefmt.toml will look as follows:

command = "nixpkgs-fmt"
includes = ["*.nix"]

command = "rustfmt"
options = ["--edition", "2018"]
includes = ["*.rs"]

Before specifying the formatter in the config, make sure its installed.

To find and share existing formatter recipes, take a look at the docs.

If you are a Nix user, you might also be interested in treefmt-nix to use Nix to configure and bring in formatters.


treefmt works with any formatter that adheres to the following specification.

For instance, you can go for:

  • clang-format for C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C#
  • gofmt for Golang
  • Prettier for JavaScript/HTML/CSS

Find the full list of supported formatters here.

Upcoming features

This project is still pretty new. Down the line we also want to add support for:

  • IDE integration
  • Pre-commit hooks
  • EditorConfig: unifies file indentations configuration on a per-project basis.
  • prettier: an opinionated code formatter for a number of languages.
  • Super-Linter: a project by GitHub to lint all of your code.
  • pre-commit: a framework for managing and maintaining multi-language pre-commit hooks.


All contributions are welcome! We try to keep the project simple and focused. Please refer to the Contributing guidelines for more information.

Moving from Rust To Go

You may be familiar with Version 1, which is written in Rust. So, why re-write it in Go?

Ultimately, treefmt is spending most of it's time shelling out calls to the underlying formatters. This process is just as fast/performant in Go as it is in Rust.

The remaining tasks are processing some cli args and parsing a config file. Do we really need something as heavy duty as Rust for that?

Despite all this, you can make good, sane arguments for continuing with Version 1 in Rust instead of a re-write. So here's a bad argument.

Brian wanted to improve performance by moving away from a Toml cache file, introduce pipelines for applying multiple formatters against the same file set, and add an extensible approach for how treefmt walks file systems. He knows Go much better than Rust.

zimbatm thought it was a good idea too.

So here we are 🤷.

Just Use Go

Commercial support

Looking for help or customization?

Get in touch with Numtide to get a quote. We make it easy for companies to work with Open Source projects:


Unless explicitly stated otherwise, any contribution intentionally submitted for inclusion will be licensed under the MIT license without any additional terms or conditions.