aruarian.dance1577 words8 min

You do not need NixOS

Imagine someone came up to you and told you that there exists a perfect Linux distribution. One so perfect that, as long as you take the time to learn its arcane syntax and strange conventions, you can obtain powers that a sysadmin can only dream of. A way to describe a machine through code once, and have it never break again. No longer will you have a broken display server after an update, or have to figure out a new configuration format for a service you want to run. Everything can be declared in a single file, in a single language, and reproduced on any other computer with a single command.

You start seeing this distro mentioned everywhere. You see Hacker News threads on it. Videos about it appear on your YouTube home page, even though you haven't watched a Linux video for months. Your dog starts barking about build reproducibility (or maybe that's just a weird dream?). You'd be an idiot to not instantly switch all of your Linux machines over to it! Why aren't you using it already?

This is how I felt when I first learned about NixOS. I fell in love with the idea, but after spending a year with it, I couldn't learn to love the implementation. The hook of NixOS is obvious to anyone who's ever had to manage a Linux machine. Hell, it's obvious to anyone who's had to manage a computer, ever. The idea of a reproducible build solves the problem of "I (fixed this issue/set up this service/did this thing) in this very specific way, but I can't remember how to do it again", and it's certainly a noble problem to solve! But one question that I almost never see brought up is, do you actually want this?

A lesson in pain

I got my Framework 13 laptop in November 2023. Before I had been using Manjaro on my desktop computer, after a while of hopping from Mint to Ubuntu to Arch. I could already feel the issues of using Manjaro day to day, so with my fresh new laptop, I wanted to step outside my comfort zone and try NixOS. I had read a bit about it, and decided that I had to try it out. It took maybe 3 days to get it to a usable state with an X server and desktop, and a few months afterwards of gradually tweaking the system to get all of the issues ironed out. If I found that I needed an app, I would configure my system to add it in, along with all of the specific configuration that I wanted - and since I pushed it all to a Git repo, I was able to track the state of my system over time, to see what changes I had made to the configuration and when. I had a lot of problems during these few months, which many others have already summarised - the documentation is lacking, the errors are opaque, and it feels like there's infinitely many ways to do a single thing. But ultimately, I had a working system where I knew every single thing I had configured, all from a single place.

Along with my Framework, I also bought a Belkin Thunderbolt 3 dock to go along with my laptop. This dock did not work out of the box, but worked fine on liveboots of other distros like Fedora Workstation. I spent way too long trying to figure out why it wouldn't be recognised by my laptop, until I found the services.hardware.bolt.enable option. Absolutely a skill issue on my part, but afterwards I was just left thinking, why is this something I have to explicitly enable? Why can't things just work?

I also constantly ran into problems when trying to develop apps and write code across a variety of tech stacks. NixOS heavily discourages you from making your desktop environment the same as your development environment (which is good!), but it doesn't give you an easy way to create a development environment for a specific project. The encouraged solution in the NixOS community is defining a flake.nix or a shell.nix in your project's root directory, and a .envrc which switches into that environment when you open it in a terminal. However, this means that your projects end up populated with Nix files, which is particularly annoying when you want to submit PRs to upstream projects - it just adds clutter to your PR, and it would be rude to have a maintainer accept (and maintain) this new flake.nix alongside their own code. On top of that, IDE support for .envrc varies wildly, and my preferred editor Zed did not have support for it at the time.

After about a year of using NixOS, including using it for work, I ended up switching to Bazzite, and eventually Bluefin - both based on the immutable Fedora Silverblue distro, tackling a similar problem to NixOS but in a different way. Whereas NixOS has you define your entire configuration upfront, the Silverblue-based distros offer:

  • Flatpak for graphical apps
  • Homebrew for CLI apps (yes, you can get Homebrew on Linux; I was surprised too!)
  • Distrobox for cases in which you need a specific Linux environment, via Podman containers
    • Side note: this entirely solved my problems with having to define a dev env for a specific project. If I work on a repo, all I have to do is enter my dev distrobox, SSH in from my IDE, and work within that environment - no devcontainer or flake.nix required.
  • Layering packages on the system level, as a last resort

But most importantly, the philosophy of reproducibility and "don't touch my system files" from NixOS lives on in Silverblue as well.

I don't want to care

After switching, I immediately realised that the experience of using my computer became much easier, but I had trouble articulating exactly why it's easier. I think the entire time that I was using NixOS, I never stopped to think if I should. Yes, NixOS is incredibly powerful and you can make a reproducible system which will never break after you set it up once. But that also means that:

  • I'm now responsible for configuring this entire system
  • I am also responsible for updating this system

These are not things that I want to worry about when I want to just use my computer! If I was still heavily into ricing and i3 and polybar like I was when I was younger, then perhaps NixOS would be more appealing. But as someone who wants to use a computer like a regular person to do regular work, the ability of my OS to get out of my way and let me do things far outweighs any benefits I get from a perfectly reproducible system. Yes, I could reproduce the same system configuration on 100 different computers if I wanted to - if I actually had a need to.

I sum this idea up as, "I don't want to care". It's not "I don't care", because that's just not true. I care about my desktop working, and I care about being able to update without things breaking. If I want to start using a Japanese keyboard layout, I want to be able to just go to the settings and add one; rather than research what an IME is, and whether I should use ibus or fcitx5, and what configuration options to set, and...

But I don't want to care about how it happens; if it means I have to sacrifice perfect reproducibility, then so be it. While writing this post, I found the post Don't use NixOS to resonate a lot with me in this aspect, and I ended up relating to the author's conclusions.

The path forward

I believe that the core idea of NixOS is fundamentally opposed to the idea of what the average person wants in their desktop. Instead, I think this role will be better filled by immutable distros like the already-mentioned Fedora Silverblue and its derivatives. Containers, love them or hate them, have become a staple of the sysadmin world, and I don't see why they can't work on a desktop machine just as well as a server. This doesn't mean that immutable distros are without their issues, most importantly the sandboxing: some features just don't work. I still can't get WebUSB working in the Chromium flatpak, meaning I can't configure my keyboard using VIA (note: this turned out to be a different issue with my QMK configuration, and WebUSB actually works fine!). However, the benefits of an immutable system with a mutable home and containers is so obviously a good thing I can't see how people will be moving away from it.

On the server, however, NixOS is an incredibly good choice, and it's what I'm currently using to build my VPS on. If you configure impermanence and ephemerality, then you don't have to worry about configuration cruft or persisting useless data. Since I might even move my services from my VPS to hardware in my homelab in the future, the reproducibility and deterministic build capabilities make even more sense. The improvement in ergonomics over Docker compose files is noticeable, and with the experience I've gained from using NixOS on the desktop for a year, I'm sure I can reap the rewards of it on the server.

tech linux