Nix is a functional package manager. This makes it different from a lot of popular package managers, like pacman, apt, or yum. It’s much more closely related to GNU Guix, albeit with less LISP - in fact, Guix is based on Nix! The big claims to fame with FPMs are rollback, environment isolation, and being able to have multiple versions of programs and libraries installed on the same machine. I will go into more detail about all these attributes and more, later.

NixOS is the Linux distribution that uses Nix as the package manager. It has two officially maintained “channels” - a stable channel (NixOS 14.10) and an unstable channel (rolling release). Despite the name, updates are only released to “unstable” when they are successfully built and tested by the build farm, so in practice, it’s still pretty reliable, and that’s what I use on my laptop right now.

This blog post is about my experience with Nix and NixOS.


My first attempt to try NixOS was a bit of a flop, but it could have worked if I was just a bit less in a hurry to learn it all at once.

The one thing I did cautiously was that I installed NixOS to a VirtualBox machine. NixOS runs pretty well in VirtualBox, which shouldn’t be a surprise in this day and age. The graphical live environment uses KDE, but you’re free to install other WMs and DEs.

NixOS is designed to be configured at the system level via a single config file, /etc/nixos/configuration.nix. This is written in Nixlang (you’re probably not supposed to call it that, but it’s less confusing if you do), the same language that the package database (and manifests) are written in. It effectively imports the package database, and leaves it up to you to construct a system out of it by enabling or disabling services, configuring your filesystem mounts, and so on. If you want to try out your updated configuration, run nixos-rebuild switch, and Nix will do its darndest to update the state of your live system, installing packages as necessary.

Anyways, my problem was that I tried to configure my system in an aggressively custom way, from the start. I thought I would be clever, using Wayland instead of X, and various other decisions that I did not incrementally test. When I rebooted into my new operating system, it was hilariously broken. Fixable, and I put a bit of work into it, but it was enough work that I lost motivation and went back to working on DJDNS.

If I had started with a more boring config, closer to the example, I would have been able to have a working system to experiment from. And any configuration change that ended up breaking things, I could have just booted into a previous config via grub. In fact, when I installed NixOS on my laptop, I did end up doing this on one occasion - it was fantastic to be able to boot into a previous configuration, fix the problems in configuration.nix, and try again.

Lesson 1: Always start with a reliable system config, then work in small increments, so you can use rollback to recover from screwups.

Making it work on the laptop

Take 2. While Nix can be used on any distro, I figured the only way to truly learn Nix was by immersion. This turned out to be a really good call - nothing motivates like having your system’s usefulness dependent on figuring stuff out.

Most of this was actually pretty easy. You just refer to the manual (man configuration.nix) and implement the stuff you like, a piece at a time, through trial and error. The one thing that took a long time was configuring my wireless network. NixOS currently has a bit of an unfortunate focus on servers (not surprising, given the admin and compatibility and safety properties), which means that it’s a bit underdocumented how to effectively and conveniently configure a laptop. You are honestly recommended to play with wpa_supplicant.conf manually, which is hilarious these days, to modern Linux’s credit.

The good thing was that it actually supported my ethernet jack properly, which Crunchbang never did, so I was able to use the internet to download packages. I was just tethered. But for a laptop, that’s still a great enough indignity to push me to fix it, as well as a helping hand to get the problem solved.

After messing around with WICD for a long time, since I’d had better luck with it on Crunchbang than NetworkManager, I eventually got past old habits and tried NM on NixOS. Worked like a charm! Which, after hours of troubleshooting, is always a combination of facepalm and relief. The relevant lines in my configuration.nix:

networking.enableIPv6 = false; # To make wifi work
networking.networkmanager.enable = true; # Use nm specifically

Lesson 2: To make wifi work, just use NetworkManager and, if necessary, disable IPv6.


Not part of my personal experience, but something I want to bring up before the end of the post - and this is around the point where I was convinced by the pattern I was seeing in IRC.

Lesson 3: Don’t bother running Nix on other operating systems.

That’s going to be controversial, because Nix works very well for installing programs for local users without root permissions. The problem is that it’s never enough - everyone always wants to install nginx or sshd or whatever the hell, and the system service packages are designed to work on NixOS - installed via system-level config, on a platform with systemd. The common solution given to people is that they have to write their own Upstart configs, shell scripts, etc., depending on their platform. Which, of course, completely negates any effort savings or administrative sanity that you’d get from using Nix.

Sooner or later, you’ll run into this brick wall, and as long as nixpkgs service packages don’t play nice with other OS’s, Nix will continue to be a toy package manager on third-party distros. In fact, given that system services are one of the first things new users itch to install with Nix, I’d argue that there is very little value to encouraging new users to “try before you buy” Nix on their current system, when it’s only really useful and easy and “free” on NixOS. I’ve seen a lot of users come away with a bad impression of Nix because it was ill-suited to running on Ubuntu, Fedora, etc.

If you want to learn Nix, run it in a VM or on bare hardware, not as a hobbled package manager on your current distro of choice.

Contributing back

It’s pretty sweet to be able to install things to my own personal non-root environment. While I have the i3 window manager installed system-wide, a lot of the personal goodies - nitrogen, xfce4-terminal, network-manager-applet, etc. - are installed as user ‘philip’. This is a bit more convenient for concisely taking an inventory of what I’ve got installed, but there was a program I was missing - pnmixer.

pnmixer is easy to build, but it’s not packaged in any operating system I’ve used before. I always have to build it myself. I like it because it works directly with ALSA, it’s lightweight, and it supports the features I need (for example, it has scrolling functionality and you can configure which mixer program it uses).

NixOS has an incredibly approachable package contribution process, and I wanted to learn how. So I cloned the nixpkgs repo, made a feature branch, copied an existing mixer applet package definition (which was ineligible for my use cases, as it worked with PulseAudio), and tweaked as necessary. Finally, with a few extra changes here and there as necessary, I was not only able to build the package for personal use in an automated and isolated environment, but I was able to submit the changes as a pull request! It has since been built by the automated build farm, and the binaries are publicly available for anyone on the i686 or amd64 architectures on Linux.

If you’ve never contributed to a distro before, you don’t know the rush it is. It’s a very similar phenomenon to Wikipedia - by making it easy to contribute, without lowering the bar for quality, anybody can provide new or updated information, anyone can improve the gigantic resource that everyone relies on. It’s incredibly fulfilling, and feels like the kind of pseudo-democratic beauty that is necessary for any large-scale distro maintainership.

The reason such a small core team can administrate such a massive undertaking is because of the automated build farm. The Hydra software (obligatory “Hail Hydra”) runs the test suite for every package it builds, where available. Changing a commonly-depended package will trigger a rebuild of everything that depends on it, and everything that depends on those, and so on, leading to sweeping “generations” of rebuilds - and if there are any packages that fail to both build and test okay, that whole commit in the nixpkgs repo is considered to be a failure, and the publicly available set of packages remains unchanged.

The one big problem with this model, is that it can take awhile for security updates to be released, because even changes to dynamic libraries trigger a rebuild/retest for their dependent packages, and the security-fixed library will not become available until that entire nixpkgs commit has been confirmed successful. This can delay security fixes for awhile. On the other hand, it helps use machines to take a lot of load off of manual maintainership, which can be focused on improving the packages in more featureful ways, and testing long-term stable releases thoroughly.

Lesson 4: Contribute a package. It’s good for the world, makes you feel like a champ, and learns you some Nixlang.

NixOS still isn’t perfect

The security-critical release story still isn’t great, like I said. There’s still a limited set of packages (although you should see this as an opportunity to contribute - get it before it’s gone!). Nixlang is not only conceptually foreign to a lot of programmers, it’s slow as butts on large package databases, at least on memory-constrained devices. I did actually install kcachegrind to analyze nix-env, and Nixlang allocates mucho objectos. There’s still gaps in documentation, and disagreement over which tools are still even relevant! And it’ll be interesting when my machine has been running NixOS long enough for me to need to play with the nix store garbage collector, or the update mechanisms. And as much as I enjoy it, I wouldn’t recommend it for my family members, any more than I would recommend Arch (my sister really enjoys Ubuntu, I’m trying not to throw away goodwill where I got it). It just will not be noob-friendly for a long time, if ever.

All that aside, I believe these issues are all fixable, and will be fixed as more people try (and fall in love with) NixOS. She’s worth the love.

Where to next?

Or should I say “nixt”? No, no I shouldn’t. Even for me, that was a terrible pun.

I’d like to package my own software, once the community comes to some sort of decision how to package Go binaries and libraries. And while I don’t consider it “my” project, I’d love to package Journey to the Center of Hawkthorne.

I’d like to contribute to Wayland/Weston packaging, so that I can trivially install GNOME Shell Wayland Edition alongside my daily driver i3 setup. Not that I’m a GNOME Shell fan, but I’m the worst Wayland fanboi, y’all have no idea.

I’d like to contribute performance and tooling improvements to Nix itself, making it faster and more user friendly.

I’d like to run NixOS on my servers, because it affords so much better isolation and administration capabilities than Ubuntu. I have lived with, and loved, Debian and its derivatives my entire Linux-using life, I still harbor them zero ill will, and I would still not feel bad if I never used any of them again on machines I own, because NixOS gets so many things right-er, and solves my real-world problems in ways that other distros are structurally incapable of.

I’d like to see nixpkgs maintainers engage in a positive discussion of how we could bring system-level configuration to other distros. I don’t mean that the answer should necessarily be “yes let’s spend our time on that,” but if it can be done sanely with the help of automated testing and volunteers, maybe it’s an idea that deserves to live, and eventually thrive. It would be nice if Nix was a non-toy on other distros, but if not, it should be more honestly advertised as “just” a local installation tool, and work at fulfilling that niche more snugly.

Finally, I’d like to convince more impressionable geeks to join our little cult. It’s surprisingly sane and productive in here. I do have to warn you that it may spoil you - even if you walk away believing that it is not quite right for you, it will forever alter your perception of what a next-generation distro should strive for, and the features it should make not only available, but convenient.

I truly believe NixOS is one of the next big things that will happen to Linux in the near future. A couple other big things will probably roll to fruition first, but Nix’s Eternal September is coming, and my /dev/body is ready.