Skip to content

6 Reasons Why I Love Nix

I found out about Nix from a good friend of mine. First time I heard about was thinking why would someone put so much trouble for little beneift but now that I have been running it for a year, I can’t imagine my dev life without it. Here are 6 reasons why.

Nix is an OS, a package manager and build system that treats your software environment as code. In this blog, we will use the latter two in a way that allows you to describe exactly what you need (packages, versions, tools), and Nix builds it in isolated, reproducible paths, so the same config produces the same environment across machines.

1) Reproducibility that actually stays reproducible

Section titled “1) Reproducibility that actually stays reproducible”

Pin nixpkgs and your environment stops drifting: today, next month, and on a totally different machine.

Nix installs packages into isolated paths, so versions can coexist without stepping on each other. Upgrading one thing does not quietly break three others.

3) One config rebuilds my whole setup (homelab included)

Section titled “3) One config rebuilds my whole setup (homelab included)”

This is the part I love: I can take a blank machine and rebuild it from config: packages, services, users, settings. Same approach for laptops, servers, and homelab nodes.

warning I did notice though that it does use a surprising amount of storage, so I’d recommend using Nix for this purpose only if you have enough space in your computer.

4) Dev shells that do not pollute the system

Section titled “4) Dev shells that do not pollute the system”

nix develop / nix-shell gives me project-specific environments (exact language versions, system libs, tooling). Exit the shell and my base system is untouched.

On NixOS, if an upgrade or config change goes sideways, I can reboot into the previous generation and I am instantly back.

6) Less fragile infra (and better for teams)

Section titled “6) Less fragile infra (and better for teams)”

Shared configs make onboarding: clone repo → enter shell → run. Plus caching/binary caches mean fewer rebuilds and fewer “it broke because something updated overnight” surprises.

Nix optionally uses something called flakes to make sure your inputs (soruces) are consistent and right now is the modern nix setup. While I might explain how to kickstart nix in another blog, here is a little example of a flake.nix file to investigate.

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