Skip to content

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.

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.

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.

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.

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.

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.

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.

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)"
'';
};
});
}