·6 min readtech

NixOS: The Distro That Can Never Break

#nixos#linux#infrastructure#devops

Half a Decade on Arch

I used Arch Linux for half a decade. I fell in love with pacman, and the AUR. If you've used Arch, you know — the AUR is way more comprehensive than anything Debian-based distros like Ubuntu can offer. Need some obscure package that only three people on the internet use? It's in the AUR. Someone already wrote the PKGBUILD. Arch was home.

Then a stroke of unknown force led me to NixOS.

A completely new paradigm of Linux. Not just a different package manager. Not just a different init system. A fundamentally different way of thinking about what an operating system should be.

Declarative Everything

The package management in NixOS is declarative. You don't install packages by running commands. You write a configuration file — configuration.nix — that describes your entire system. Every package, every service, every kernel module, every user account. The whole machine, declared in a single file.

{ config, pkgs, ... }:
 
{
  environment.systemPackages = with pkgs; [
    vim
    git
    firefox
    htop
  ];
 
  services.openssh.enable = true;
 
  networking.firewall.allowedTCPPorts = [ 22 80 443 ];
}

You write what you want. You run nixos-rebuild switch. The system becomes what you described. That's it.

And because it's just a file, you push it to a git repository. Your entire machine configuration — version controlled, diffable, reviewable. Set up a new machine? Clone the repo, run the rebuild, and you have an exact replica of your system. Not "similar." Not "close enough." Exact.

It Can Never Break

This is the part that sold me. Every time you rebuild your system, NixOS creates a new generation. Each generation is a complete, bootable snapshot of your system state. They show up in your boot loader as separate entries.

Decided to try a bleeding-edge Linux kernel? Go ahead. If your machine breaks, reboot, select the previous generation from the boot menu, and you're back to exactly where you were. No troubleshooting. No digging through logs. No reinstalling. Just revert.

You can experiment fearlessly. Try a new desktop environment. Swap out your display manager. Enable some experimental service. If anything goes sideways, the previous generation is right there. One reboot away.

And yes, you can clean up old generations at your discretion. nix-collect-garbage -d wipes them when you're confident you don't need them anymore. But until you explicitly do that, every previous state of your system is preserved and bootable.

On Arch, a bad pacman -Syu could leave you in a broken state that takes hours to fix. On NixOS, that problem literally does not exist.

IaC, but on Machine Level

This is what I fell in love with the most. If you've worked with infrastructure-as-code tools — Terraform, Ansible, Pulumi — you already understand the philosophy. You declare the desired state, and the tool makes it so.

NixOS is that, but for your actual machine. Not a cloud VM. Not a container. Your laptop. Your workstation. The thing you sit in front of every day.

Think about what that means:

  • Reproducibility. Two machines with the same configuration.nix are identical. Not "roughly the same." Identical. No more "it works on my machine" between your desktop and your laptop.
  • Auditability. Want to know what changed? git diff. Want to know when it changed? git log. Your system configuration has the same traceability as your application code.
  • Disaster recovery. Laptop died? Buy a new one, clone the repo, rebuild. You're back in business. No spending a full day reinstalling packages and tweaking configs from memory.

On Arch, my setup was a collection of tribal knowledge — packages I installed months ago that I forgot about, config files scattered across /etc and ~/.config, shell aliases I'd never remember to recreate. If my drive died, I'd lose all of it. On NixOS, my entire setup is one git clone away.

The Learning Curve? Not Anymore.

In the pre-AI days, sure — NixOS had a steep learning curve. The Nix language is its own thing. A functional, lazily-evaluated language that looks nothing like bash or Python. The documentation had gaps. You'd spend an hour figuring out how to do something that would take ten seconds on Arch.

But now? With AI, it's a breeze. You describe what you want your machine to do, and AI writes the Nix configuration for you. You can fully customize your OS in any other distro too — but the declarative design of NixOS makes it fundamentally unbreakable and highly manageable. That's the difference. Other distros let you customize. NixOS lets you customize without consequences.

And once your configuration is written, it works forever. On Arch, I was constantly maintaining my system. On NixOS, I maintain a file. The system maintains itself.

Flakes

If you're getting into NixOS today, learn Flakes. They're technically still "experimental" but everyone uses them. Flakes give you pinned dependencies for your system configuration — meaning your build is reproducible not just across machines, but across time. The same flake.lock file guarantees the same packages, the same versions, the same result, whether you build it today or six months from now.

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  };
 
  outputs = { self, nixpkgs }: {
    nixosConfigurations.my-machine = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [ ./configuration.nix ];
    };
  };
}

This is the flake.nix that pins your entire system to a specific snapshot of nixpkgs. When you want to update, you run nix flake update, review the changes, and rebuild. Controlled, predictable, reversible.

I'm Not Going Back

I still have respect for Arch. It taught me how Linux works under the hood. The Arch Wiki alone is one of the greatest resources in open-source history — and it's still useful on NixOS, because Linux is Linux.

But NixOS changed how I think about system configuration. It's not a chore anymore. It's not something I do reluctantly when things break. It's a declarative specification of exactly the machine I want, tracked in git, reproducible anywhere, and revertable at any time.

IaC on machine level. That's the best way I can describe it. And once you experience it, going back to imperative package management feels like going back to writing deployment scripts instead of Terraform.

You can take my Arch install. I'm not going back.