Devs Should Give NixOS a Shot
== *** ==

Devs Should Give NixOS a Shot

Est. 6m read

I’ve been using Linux for over 10 years now (sheesh) and only in the last year did I find the distro of my dreams. In this post, I’m going to try and explain why I like NixOS and how I’m using it. If you’re anything like me, switching will be a no-brainer.

Over the years I’ve been through several of the popular distros. Last year, I gave Fedora a shot after losing all my data. I heard it had a reputation for being stable but within a few months I had issues with my display flickering, problems unmounting disks, and several other issues that I can only attribute to a corrupted OS.

Clearly something had changed because Fedora was working just fine a few weeks prior, but I had no way of knowing what changed…

As soon as Fedora started acting weird I started plotting my escape. For the next OS, I knew I needed to start putting stock into reproducibility. I began my research with Fedora Silverblue. After reading their product page and doing some research in the Fedora forums, I was not convinced that Silverblue’s failsafes were going to be enough to prevent a corrupted system file from wreaking havoc again. Silverblue also sounded incredibly restrictive, but that’s when I remembered NixOS…

I started reading through NixOS configs from the anime pfps of GitHub and it wasn’t long before I started to see just how powerful a Nix config could be.

Unlike most other Linux distros where the setup is scattered across hundreds of files and directories, NixOS is a declarative system where your applications, desktop settings, and plenty more are tracked in git and can be completely reproduced with a single command:

$ sudo nixos-rebuild switch --flake .#my-config

Instead of copying files, NixOS mostly uses read-only symlinks to /nix/store/.... This has several advantages, my favorite is that uninstalling a package rarely leaves behind stray files. Often, in other OSes, even after uninstalling the app I can find folders filled with supporting files or configuration taking up precious disk space. This has been much less of an issue since switching to NixOS.

macOS “Other” in the Storage tab
Many other operating systems seem to just keep growing

Another great thing about this approach is how modular it is. You can imagine the Nix ecosystem as 100,000+ kinds of different Lego bricks and it’s up to you and your config to assemble them. There’s a brick for Google Chrome, Emacs, TeamViewer, Steam, OBS, Wayland, Hyprland, KDE Plasma, Python, NodeJS, Elixir, your favorite npm/pip packages, and so on. You can basically build your own distro.

One downside to this approach is that if the thing you’re after isn’t in Nixpkgs, it can be challenging to install. I’ve only found one package that wasn’t in Nixpkgs and considering AdsPower didn’t work on Fedora either, I’m not deducting any points.

How I’m Using NixOS

My main “machine” is named nixos which I admit is a bad name. If you look at the config, there’s a default.nix which imports several modules. For example, modules.linux is a module I wrote that installs all of the CLI tools I’ve come to expect on Linux. If I wanted to create a config for a new “machine” I can place this modules.linux in there and expect the same CLI tools to be there too.

Once my config was exactly how I wanted it, I got the urge to see how easy it would be to reproduce it on another computer. My only options were a Raspberry Pi1 and a MacBook Air…

NixOS on a MacBook?

I had always wanted to try Asahi but never had a good enough reason to, this was my chance.

There’s this guide from the Nix community for installing NixOS on Apple silicon. I fed it to Claude and had it walk me through the process. The first part was very easy, just a curl | sh command. I set how much disk space NixOS should use (45%) and then was instructed to reboot into the recovery state.

Instructions

Like usual, I had to create a live USB with the NixOS installer on it. In this case, I got to build the ISO myself with:

nixos-apple-silicon$ nix build --extra-experimental-features 'nix-command flakes' .#installer-bootstrap -o installer -j4 -L

and I’ll write more about this below, but because they’re using nix build to build the ISO, it only takes one command to build it with Apple silicon support. I think that deserves a point.

But this next part stumped me for a full day…

I was able to boot, but there’s a step during the guide where you need to connect to the internet with iwctl. I tried everything and still couldn’t get the internet connected. The only clue I had was “brcmf_cfg80211_escan_handler: invalid event data length” which sounded like a driver issue but I had no clue how to fix it.

During this downtime, I realized that my nixos config (a.k.a. my desktop config) was not suitable for my MacBook. So I quickly put together a new machine named mba that is slightly stripped down.

I then posted a GitHub issue about the iwctl situation and got the answer much faster than I expected. @zzywysm explained that I could fix the driver issue by changing 3 lines in the Nix files used to build the ISO. I’m kind of surprised this isn’t the default and that I’m the only person who has reported it.

Anyways, with the new ISO, I was feeling confident…

Building the kernel
Building the kernel took over an hour
Seeing U-Boot for the first time
This sure looks promising...
sddm lockscren
Success!

Just like that, with a single command, I’ve got my user account, desktop environment, git config, SSH keys, applications, etc. ready to go. It has never been this easy.

What Else Can “Nix” Do?

Probably like many other devs, my first time learning about Nix was through GitHub repos with flake.nix and flake.lock files. For many years I just ignored them, “I don’t use NixOS” I thought- but as it turns out, I could’ve been making use of them on macOS, Windows (WSL2) and any Linux distro.

So what do they do? These flake files are extremely similar to the Nix configs mentioned earlier. They’re modular environment definitions that can manage every dependency. No more installing libxyz-dev, just nix develop and the entire dev environment is prepped. This makes reproducibility insanely simple and will certainly make the entire triaging process easier.

One ability that really changed the way I saw NixOS was the nixos-rebuild build-vm command. You can clone any config and run build-vm and NixOS will create a VM right there. This is great for trying out other people’s setup without changing your own.

build-vm

The Nix config reminds me of the Emacs config. You bite the bullet and build out a configuration one time and you can use it everywhere and it “just works.” I’ve heard there are Emacs users who have been keeping a config for 20+ years. Seeing as I’ve battle tested NixOS for several months and have nothing bad to say, I can imagine keeping a Nix config for 20 years too.

I didn’t even scratch the surface for what NixOS has to offer but if you’re a developer, I recommend you use NixOS as your daily driver. If you’re a Linux enthusiast, you should consider it and if neither of those apply, I withhold my recommendation.