A Love Letter to NixOS

A Love Letter to NixOS
Photo by Lukas / Unsplash

I've been using NixOS as my daily driving OS for a bit over a year at this point; I had tried to get into Linux a couple times before this and bounced off every time, but it's finally stuck with Nix. And I'm very aware that NixOS has its problems; it's not a perfect distro that everyone should change to, it very definitely is not that. I'll talk about some of the problems I've had with it, and for someone less tech-savvy it would have been even worse. Still, I have come to really adore this distro, and I'm going to share with you a couple of the reasons why.

What actually is NixOS?

For those who haven't heard of it, NixOS is a weird, weird Linux distro. NixOS is built around the Nix package manager, and honestly, it's just completely different from how you're used to computers working. In most operating systems, when you install a program, it dumps files all over your computer - some in /usr/bin, some in /lib, some who-knows-where. But in Nix? Everything gets its own isolated folder in the "Nix store," with weird-looking hash names that make sure different versions never clash. Here's the really cool part: your entire system - from what programs are installed to how your desktop looks - is defined in plain text configuration files. As a result of this "declarative" approach (called as such because you're "declaring" how you want the system to be configured, rather than doing the explicit command running yourself), your entire OS becomes almost like code - you can version-control it, branch it to test different changes, and share it with others. Another amazing thing about Nix is how it handles dependencies.In other operating systems and distros, when you install a package it can request dependencies; if it asks for a dependency that already exists on your machine, but at a different version, the one already on your machine will be overwritten by the newer/older version the package you're installing wants. This can break a different program that depended on the old version of the dependency! This nightmare scenario is basically impossible with Nix. Because everything lives in its own directory in the Nix store, with all its dependencies precisely specified and living in their own isolated directories in the Nix store, multiple version of the same library can be happily installed together with no issues. This can especially make life easier for programmers, who may need to regularly use multiple different versions of Python, Node, Cargo, and whatever else. Now that can all be done on the same system, without using Docker or anything like that, all with zero conflicts. If you've had to deal with the alternative, and the struggle of two programs you need being mutually incompatible, it is really astonishing how the problem just vanishes.

NixOS is forgiving

Every other time I've tried Linux, things went well for a day, or a week, or a month. And then I need to do something a bit weird, look up how to do it online, don't really understand what I'm doing, execute some command, and something breaks. I try to fix that by the same process, and something else breaks. And this gets to the point where either the computer is unusable, or I get too frustrated, and I swap back to Windows. This basically can't happen with NixOS. Instead of running shell commands to change your system, you update your configuration files and apply it. And if this has royally screwed something up? You can pretty much always undo. In the first couple weeks after I started NixOS I tried to do another one of these "I don't reallyy get how this works but what if I..." moves. Namely, I had an internal drive which I had to manually remount every time I turned my computer on, and wanted to figure out how to get it to automatically mount. I looked things up, added some stuff to my configuration files, and boom; System no longer boots. Shit. With any other Linux distro, that would have been the end of that and back to Windows I go. But on NixOS, approximately all system configuration flows directly from your single set of configuration files. Whenever you update those files and push the changes to your system it adds a record describing the new configuration, and updates the system state accordingly. But it doesn't get rid of the previous record describing the previous configuration! And every single configuration (that you haven't deleted) can be booted into, meaning if you make a change to your configuration files and the resulting system can't be booted into? Well, it's as easy as booting into the previous configuration, changing the default boot configuration back to the old one, and being on your way. That was the moment that made fall in love with NixOS.

NixOS is fun!

Look, I'll be honest. If you're actually using NixOS, this is one of your hobbies. I semi-frequently take some time to tinker with my configuration files to add some new system, redo how I've structured part of it, or change what my colour scheme looks like. Doing the little problem solving loops to figure out how to get some weird thing working is just satisfying.

But: NixOS is frustrating

Definitely not all sunshine and rainbows here. NixOS is structured very, very weirdly compared to any other Linux distro; no files are where any program expects those files to be (at least in terms of system libraries and similar). And this is pretty critical for NixOS to be able to fully solve dependency conflicts, but it does mean that approximately every single piece of software needs some custom wrapping around it to make sure it has access to all the libraries and other dependencies it expects, at the versions it needs. For things that other people use all the time this is basically a non-issue; but if you semi-frequently clone random GitHub projects to try them out, as I do, you will run into Problems. Basically you'll need to package the project yourself, and this is often a non-trivial task.

And this is also often an issue for very new programs that haven't been nixified yet. There's some escape valves (Flatpacks and Snaps work normally), but it's not a stupendously rare occurrence for me to not be able to use a fancy new program because no one has ported it yet, or not be able to use some fancy new feature in an existing program because the packaged version in nixpkgs isn't up to date with the latest version.

NixOS is ambitious

The problems with NixOS are decidedly non-trivial. For anyone who isn't confident in the terminal it will be utterly unapproachable, and even for those of us who have there are frequently problems, and weird unintuitive complications. But I can forgive many rough edges of any project that is doing something hard, and weird, and ambitious. And Nix's pitch is so ambitious! Fully declarative system configuration! Control your whole system from one Git repository! No more dependency conflicts! Every computer you use having the exact same programs installed, fonts, configuration, trivially! Nix claims that if you use it you will never again have to deal with vast swathes of the hardest problems that you run into on other distros, and it basically succeeds at this pitch! Trades them for its own suite of problems, sure, but it does basically solve them. I just find this kind attitude towards making and running projects so inspiring, and in turn I love the project.

Trying it out

If this has made you at all interested in Nix; I would recommend not trying out NixOS 😅. But you don't need to try out NixOS to try Nix! Nix is a package manager that can be installed and used usefully on any Linux distro, and even on Mac. I would honestly recommend trying out the package manager part; you get a decent chunk of the benefits of Nix (namely you can go a long way towards making your home configuration reproducible between computers and completely eliminate dependency hell), with the downsides basically not present since, by not having fully opted in, if the Nix way of doing things isn't working for whatever reason you can just use your system's normal way of installing & configuring things.