Published on

Overview of Nix Formatters Ecosystem

This post is part of a series about NixOS. The series is done in support of my upcoming Opus Magnum, "Practical NixOS: the Book", and you can read the detailed post here.

formatting

Different Nix Formatters

There are several nix language formatters currently in use:

  • nixpkgs-fmt by various contributors published under the umbrella of the Nix Community at the respective GitHub repo. Written in Rust, it is currently the de-facto default formatter for nixpkgs.
  • nixfmt by the Serokell Organization and various contributors. Written in Haskell, it is likely to be accepted as the standard formatter for nixpkgs sometime soon, see this living NixOS RFC.
  • alejandra by Kevin Amado (kamadorueda). Written in Rust, it claims to be the fastest and the only semantically correct formatter currently available.

There are also some not being actively maintained, among them:

  • nix-format by Remy Goldschmidt (taktoa), which uses Emacs to format Nix Expressions. Latest commit in 2017.
  • format-nix by Justin Woo (justinwoo), powered by tree-sitter-nix. It suggests to use nixpkgs-fmt instead in its Readme. Latest commit in 2019.
  • canonix by Robert Hensing (roberth) and Domen Kožar (domenkozar), both are veteran core NixOS contributors. This formatter also uses tree-sitter-nix. Latest commit in 2019.

nixpkgs-fmt, nixfmt, and alejandra have a playground, available at https://nix-community.github.io/nixpkgs-fmt/, https://nixfmt.serokell.io/, and https://kamadorueda.com/alejandra/ respectively. You can try all of them without installing - just visit the links, and copy-paste your nix code to see the applied formatting immediately.

Ongoing Development

As mentioned above, there is a living RFC, which aims to standardize on the nixfmt (on a side note, I encourage you to check NixOS RFCs from time to time, as they contain a lot of intersting stuff).

So far, it seems like a very thought-through set of rules for formatting, which favors readability, correctness, and ability to perform git diffing. Everyone is welcome to comment and suggest alternatives.

You may read the full document here (snapshot at the time of the writing).

Special thanks goes to Infinisil (co-author of the RFC), who gave comment on the this article and provided some valuable points:

  • The RFC does not aim to pick up an existing style, and differs completely from the original nixfmt style
  • nixfmt has been selected as foundation for its codebase, mainly because it was best suited architecturally
  • A recent PR submitted on Christmas Eve now exposes pkgs.nixfmt-rfc-style on unstable channels, making it very easy to install and try the new style out
  • The RFC is close to the final comment period (FCP), after which nixfmt is going to be both official and enforced for nixpkgs, so expect it become the community default, and a pretty soonish one

What To Choose

As evident from the announcement thread on the NixOS Discourse, alejandra claims to be the only formatter among the 3 actively maintained, that procudes "semantically correct" (or "semantically identical") code.

Now, format Nixpkgs with Alejandra, you’ll get only 89 rebuilds!!!

"Semantically correct" means that the after the formatting was applied the code does not change its "meaning" - its semantics. Some formatters may introduce differences, and such differences may vary in scope from a code producing a different evaluation hash to even a code having different behavior. With alejandra, the code after "feels" and behaves exactly the same as before the formatting.

Still, alejandra is very opinionated in how it approaches formatting, and is not configurable in any sense.

You should obviously not discard nixfmt, and expect the standardizing of nixpkgs formatting on it very soon.

Thus, I would prefer alejandra for personal stuff, while staying informed about nixfmt and expecting it to become the default (and probably the only go-to) formatter in the future.

In my next article, I am patching the sources of alejandra to use 4 spaces instead of 2. Alejandra is uncompromising, and so am I. Be sure to check the article out!

I will really appreciate, if you subscribe to my newsletter.
You inspire me to keep writing. Every reader counts.
You will receive email with link to confirm the subscription.