Hello NixOS

Over the past week or two, I’ve been migrating from Pop!_OS to NixOS. I figured I might as well write about that journey, so here I am.

My current NixOS setup
My current NixOS setup

Let’s start where all good stories start: the beginning

The calm before the storm

A long time ago, in a galaxy far, far away, a friend of mine pestered convinced me to try NixOS.

She put her dotfiles on GitHub, and I stole them took inspiration from them. Then I built my own config from there.

At this point, I was having a good time, and I was in the process porting my existing configs to use home-manager. But, then trouble started to arise.

Corruption ensues

For some still unknown reason, my nix store got corrupted in certain places. I kept getting vague Unexpected empty file errors, which were of course a joy to debug! And by a joy, I mean unproductive and painful.

These errors didn’t prevent me from installing packages in a declarative manner, but they did stop me from using nix-env commands. Sadly, home manager used nix-env so I couldn’t update my configs.

I asked in the community discord, and the official forum, neither of which could find a solution. Soon enough, I just gave up and reinstalled NixOS with a similar config.

Rebirth

This reinstallation was short-lived as I realized that this was also broken 1. This was frustrating, since apparently NixOS errors are also reproducible. I did a bunch of smaller installs, using process of elimination to find the cause of my issue.

My prior configs used both stable and unstable channels 2. But, once I tried solely stable channels, everything magically worked. In some way, shape, or form, unstable was to blame, although it’s more likely I kept doing something stupid and unstable was just involved.

A C of errors

This is the second problem I ran into, but it’s more just because I don’t know Nix too well.

As you may know, NixOS likes to store all your packages in /nix, and doesn’t bother following the FHS. Naturally, C toolchains aren’t a fan of this behavior. I referenced the NixOS wiki3, to try and find more information

The wiki page for C was kind of helpful, but didn’t have enough information for me to fully fix my issue. I was attempting to experiment with SDL2 and some of its extensions, but I couldn’t get it working.

I added a shell.nix file and the suggested flags and everything, and then ran my Makefile from a nix-shell session. And it almost worked… almost.

Of course, more errors came. The bulk of them came from SDL2_image including a file from SDL2, which would be right next to each other in a normal system. But a NixOS system isn’t a normal system, so, the #include failed.

I got pretty close to fixing this, but couldn’t quite solve it. I knew it involved pkg-config, but I didn’t know how to set it up right. This is more of a documentation issue than a NixOS issue itself, but it’s still annoying that I spent a couple hours on this and couldn’t figure it out.

The solution here was to… drum roll please… use a different graphics library. raylib, integrated into my shell.nix, works like a charm! Well, a charm that doesn’t have proper IDE support.

Because even though the NixOS wiki for C mentions how to configure a language server with the paths, it didn’t work for me 4. This is a problem I’m still ignoring solving. I couldn’t figure it out in VS Code, Neovim, or Emacs5.

The good things

Up to this point, I’ve been pretty harsh and negative. Nonetheless, I’ve had a good experience with NixOS. It’s package collection is massive6, and if you can’t find what you need, then you can write it yourself.

The idea that I can configure everything in the format is intriguing, and it works out pretty well. The Nix language is a strange one, but it grows on you.

The big picture is that there were a couple bumps in the road, but I thoroughly enjoy NixOS. It abstracts away all the little annoying parts about Linux7, and makes them simpler and increases uniformity.

The installation process felt like a compromise between normal graphical installers, and a fully manual one like Arch0. There were some manual parts (ex. I had to partition and mount drives myself), but it wasn’t too bad. And because everything is reproducible, you can just paste a basic config, and build from there.

This process creates a certain kind of magic8 that’s hard to capture for other distributions. This magic means setting up a system is fun, rather than tedious. That fun is partially why I was okay with doing tons reinstalls, trying to fix my issues. It just feels good to edit your config and see changes magically reappear.

Modules

A new concept that NixOS enables is a modular config. Basically, you split parts of your config into modules, and then can enable or disable features. For example, I might make modules for:

Then you can enable and disable these with ease. This is something that would never be possible in a normal Linux7 system. Then, if you had multiple systems, you could use the same config, and just change the modules you have enabled.

Wrapping things up

I hope you enjoyed this post, and are maybe considering NixOS. The troubles I faced were worth the power of the OS. This was my first post on here, so please let me know if you enjoyed it!

Also, follow me on Twitter pls


  1. Technically, it took a week for me to realize it, but that’s because I was away from my laptop for a week [return]
  2. Mostly just unstable for neovim 0.5 [return]
  3. It isn’t as good as the Arch wiki, but still good. To be fair, the Arch wiki is kinda the golden standard of OS wikis [return]
  4. For a reproducible OS, there sure are a lot of doesn’t work on my machine problems [return]
  5. Yes I brought out the big guns, to no avail [return]
  6. The collection itself is good, but the versions feel slightly out of date on stable. It feels like stable versions of things aren’t available yet [return]
  7. I’d just like to interject for a moment. What you’re refering to as Linux, is in fact, GNU/Linux, or as I’ve recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. [return]
  8. Although magic is usually a bad thing in programming, I mean it in a good context here [return]