A year+ of Nix: pain and how I've coped.


I’ve been running Nix for a bit over a year now, since December of 2024. There’s been many low points where I’ve considered uninstalling and just using a computer The Normal Way, but I’ve stuck with it so far, but perhaps not for the reasons you might expect.

What is Nix?

The easiest way to describe Nix is it’s a way to programmatically control what’s installed on your computer.

So instead of downloading an executable directly from the internet, or running something akin to apt install <package>, you write to a Nix config file.

As an example, here is a code snippet where I define an installation for Helix, my main text editor.

  programs.helix = {
    enable = true;
    defaultEditor = true;
  };

Of course, there’s a lot more to Nix than this, but that sums up the core of what I care about. There are a whole host of other benefits you can read more about on their website: https://nixos.org/.

What does Nix Promise?

The typical Nix pitch is deterministic reproducibility: “clone your config and rebuild your exact system on any machine in minutes.”

I don’t find that compelling. A setup script gets you 90% of the way there, and doing it manually takes maybe two hours

The main thing I want out of my computer is that it’s a tool, and I want it to enhance my productivity. So I want to be able to easily install software, and use it without worrying about anything.

Before Nix, I’ve been primarily a Fedora Workstation user all my life, and have used it for a couple years with no major complaints. It’s a reliable workhorse.

However, the main problem is that every year or so, I’ll end up reinstalling my operating system, as a whole bunch of cruft accumulates, and you end up having no idea what’s installed on your system, or how even to go about removing it.

As I was writing this article, one of my friends pointed me to https://carette.xyz/posts/going_immutable_macos/, which describes it very well, as imperative rot.

  • When you run brew install you are changing the state of your machine in a way that is difficult to reverse or replicate exactly.

As an example, if I set up a new Mac today, brew install neovim might give me version 0.10. However, if I do it six months from now, the version might changed and I had to reconfigure some components because of that change. The consequence is me, spending a few hours debugging my environment instead of writing code.

The essence of this pain is that your system becomes the sum of every command you’ve ever ran, rather than something that you can explicitly manage the state of.

Nix solves this problem.

The Pain

This all sounds good in theory, and so I was very enticed to dive headfirst into Nix and NixOS.

However, in practice, Nix has been one of the most frustrating pieces of software I’ve ever used.

I started with NixOS as my daily driver, following the Nix Flakes book as my guide: https://nixos-and-flakes.thiscute.world/.

The learning curve is admittedly steep, and the documentation on Nix is not the greatest, but with the help of the book, I was able to hobble together a pretty standard configuration in the better part of a day.

But where the pain really started was in maintaining the system, and making changes and updates.

Adding new packages can be frustrating. If what you want is in nixpkgs and works, great. If it’s outside of this happy path, things get really annoying.

I was doing a lot of hardware development and FPGA work, and most of these have vendor specific packages, and repackaging these is a lot of work, aren’t added into nixpkgs. Things like nix-ld for running arbitrary binaries are also imperfect.

Stable vs Unstable was also a point of tension for me. Unstable is frequently broken in some way that prevents you from updating your system at all.

However, stable packages aren’t up to date enough for software that ships frequent updates. For example, claude-code is frequently days behind, even on unstable.

So all of this made for a very frustrating experience, where I wasn’t able to use my computer the way I wanted to. Nix’s last of good documentation, and notoriously obtuse error messages don’t help either.

Making Nix Work

Ten months into running NixOS, I got an M4 MacBook Air (Amazon had it for $750, and my old laptop’s battery was dying). Things got a lot better after that.

First, I used https://determinate.systems, which is not the official installer, but probably should be. It made the whole experience smoother, there’s a lot more sane defaults, and parallel evals are a lot more performant.

Second, nix-darwin allows you to use nix to manage homebrew. This was a huge unlock.

Combining Nix to declaratively manage a package manager like brew allows me to solve most of the problems I had against Nix by way of having packages that don’t break and are more up to date.

This also maintains most of the benefits that Nix gives, such as being able to program out and declaratively manage my system.

In addition, something that’s helped made the experience a bit more manageable is the ability to use coding agents to help make changes and catch the errors in my config.

Should you use Nix?

Maybe. If you do, I think being a Nix purist is Not The Move.

It’s good in theory, but not great in practice. Otherwise, if you’re a student for example, I think it’s definitely a very good package manager to go and try out, and what it offers is probably going to become more mainstream in a couple years so it doesn’t hurt to learn.

Otherwise, I think the only use case where a pure Nix approach really shines right now is if you’re deploying at scale, e.g managed infrastructure, or deploying laptops to an entire school.