6 Reasons Why I Love Nix
I found out about Nix from a good friend of mine. The first time I heard about it, I thought it was a lot of trouble for very little benefit. I have been running it for about a year now, and I do not really want to go back. Here are 6 reasons why.
What is Nix?
Section titled “What is Nix?”Nix is a package manager, a build system, and an OS. In this post I only care about the first two.
The idea is that you describe what you need, so packages, versions, and tools, and Nix builds it in an isolated path. The same config then gives you the same environment on any machine.
1) Reproducibility
Section titled “1) Reproducibility”If you pin nixpkgs, your environment stops drifting. Not today, not next month, and not on a
completely different machine.
This sounds small until you have spent an afternoon figuring out why a project builds on your laptop and nowhere else.
2) No more dependency errors
Section titled “2) No more dependency errors”Every package goes into its own isolated path, so two versions of the same thing can sit next to each other without fighting.
Upgrading one thing does not quietly break three others, which is not something I can say about every package manager I have used.
3) One config rebuilds my whole setup
Section titled “3) One config rebuilds my whole setup”This is the part I actually love.
I can take a completely blank machine and rebuild it from config. Packages, services, users, settings. The same approach works for my laptop, my servers, and my homelab nodes.
4) Dev shells that do not pollute the system
Section titled “4) Dev shells that do not pollute the system”nix develop and nix-shell give you a per-project environment with exact language versions,
system libraries, and tooling.
Exit the shell and your base system is exactly as it was. There is nothing to uninstall afterwards.
5) Rollbacks
Section titled “5) Rollbacks”If an upgrade or a config change breaks something on NixOS, you reboot into the previous generation and you are back.
That is it. I still find this a little unreal.
6) Less fragile infra
Section titled “6) Less fragile infra”Shared configs make onboarding pretty boring, which is the point. Clone the repo, enter the shell, run it.
Binary caches also mean you are not rebuilding everything from source, so you get fewer of those “it broke overnight because something updated” mornings.
Example
Section titled “Example”Nix has something called flakes, which pins your inputs (sources) so they stay consistent. This is
the modern way to set Nix up.
I might write a proper getting started post for Nix later, but for now here is a small flake.nix
you can poke at.
{ description = "Reproducible dev shell (Node + Python + Go)";
inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; flake-utils.url = "github:numtide/flake-utils"; };
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; in { devShells.default = pkgs.mkShell { packages = with pkgs; [ nodejs_20 pnpm python312 python312Packages.pip go_1_22 git ];
shellHook = '' echo "Entered Nix dev shell" echo "node: $(node --version)" echo "pnpm: $(pnpm --version)" echo "python: $(python --version)" echo "go: $(go version)" ''; }; });}