>

For the last couple of months, I've been trying out NixOS on my old 2015 Dell XPS 15.

It's one of those laptops that are old enough that you can't do much on it because the CPU is pretty slow at this point, but still good enough to test some stuff with.

❯ lscpu
Architecture:             x86_64
  CPU op-mode(s):         32-bit, 64-bit
  Address sizes:          39 bits physical, 48 bits virtual
  Byte Order:             Little Endian
CPU(s):                   8
  On-line CPU(s) list:    0-7
Vendor ID:                GenuineIntel
  Model name:             Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
    CPU family:           6
    Model:                94
    Thread(s) per core:   2
    Core(s) per socket:   4
    Socket(s):            1
    Stepping:             3
    CPU(s) scaling MHz:   23%
    CPU max MHz:          3500.0000
    CPU min MHz:          800.0000
    BogoMIPS:             5199.98
It shouldn't be that slow, but not sure what's up with it

The installation experience has been pretty smooth. After using Arch Linux for 5+ years, it's definitely refreshing to be greeted by GNOME's installer again. Click some buttons here and there, and the OS is installed, wiping whatever that was previously there.

Why NixOS?

Nix itself has been on my radar for a while, but I didn't interact with it for the longest time. The idea behind Nix is to make builds and configurations declarable and immutable, this makes it easy to package and distribute software in a consistent way.

Expanding this idea to the operating system level means that system level packages and configurations can also be declarable and immutable.

There are some huge benefits for running systems in this way, but for me personally, the biggest appeal was to be able to rollback the OS when something went wrong, and there's a bit of a history till I get here.

Ubuntu

I started using Linux with Ubuntu around 2015, prior to that was OSX during college.

The initial intention was to get a better understanding of Linux by using it as a daily driver. It also helps a poor recent college grad for not having to pay for an Apple device which is not cheap, especially after moving from Japan to the U.S and there are a lot of other things to take care of financially.

This turned out great. For someone who didn't major in Computer Science, messing around with a Linux laptop helped me gained a lot of insights into how a systems work in general. Ubuntu has put a lot of work into their graphical user interface so it also didn't feel overwhelming diving into it.

However this is where I started to feel the pain of package management systems, OS upgrades and system dependency messes. I remember very well around 2016, I upgraded Ubuntu to 16.04 and the system was pretty much broken, and I had to spend a day or so trying to figure how to revert it back to 14.04. I experienced this again at 18.04 and that's when I started to think about ways to mitigate disruptions during upgrades.

Arch

When I joined Cloudflare at 2019, that's where I got a lot more exposure to Arch because there were quite a few SREs using them. I was also aware of Nix at the time, but I didn't have a lot of time to invest into something fundamentally different, and the idea of a rolling release model was appealing.

To me, it's just like how you would release software in a company. Not a giant batch every year or two, but incrementally, minimizing the changes you need, therefore reducing the risk of breaking the system entirely.

There was another interesting aspect to Arch, where you're even more exposed to the system itself. While it was a little daunting at first, Arch has one of the best documentations in Linux distros, so that gave me confidence to jump in.

Arch has been my daily driver since then, both for my personal devices and work devices. Throughout this 4-5 year period, there was probably only once the system was broken to an extend that the OS can't boot, but fixing it was pretty straightforward with the help of the documentations.

OS upgrades are no longer a problem anymore, but another problem starts to catch my attention more. User space packages, and programming language installations are getting messy.

Nix, Home Manager

I left oVice in February 2023, and was taking a couple months off to recharge. One day, when I was trying to do a system update of my device, I notice the installation failed with a weird error. After digging around a little, I realized asdf was messing with paths in a way that's confusing the system package installation, and causing the process to fail.

Since then, whenever I'm doing a system upgrade, I got into a habit of updating the PATH to exclude certain binaries prior to the upgrade itself, which felt wrong. That's when Nix start resurfacing on my radar again.

Since I'm on a break, I have the luxury of diving into something completely new, and I did the usual reading documentations end to end to get a good understanding of what I'm looking at.

Starting with nix-shell to isolate dependencies in repositories, as I grew more comfortable, I started to utilizing home-manager to handle my user space config files and package installation. This allowed me to entirely remove asdf for managing runtime, and has cleared up my user space mess a lot.

As I put more configurations and dependencies under the control of home-manager, the more hacky scripts I wrote throughout the years were able to be thrown out the window. This felt great, a lot of times I don't even remember the scripts themselves and what they do because I only needed them during laptop setup. This include a couple small Ansible playbooks I made for handling typical dependencies I need for the tools I use.

What if I can apply this principle to the OS itself as well…?

Thoughts

Fast forward to today, I've made the decision to completely switch my daily driver over to NixOS as mentioned at the start.

A couple of things I learned in the past couple of months is, thanks to the replicable nature of Nix, a lot of system configurations can be shared. There has been a couple of occasions where by just following some of the Nix documentations and references, it end up creating the system a lot better I ever did.

The setup on my Desktop was extremely smooth as well. After logging into the terminal (no GUI installation), it was basically just

  • pull down my configurations from GitHub
  • make a couple of tweaks and replace /etc/nixos/configuration.nix
  • run sudo nixos-rebuild switch
  • reboot

And everything is ready to go.

Learning flakes has also been interesting. I won't say I've fully got the hang of it yet, but I'm definitely getting there bit by bit. It feels very nice to have some kind of lockfile specifying the system depenedencies, just like how you'd lock down the dependencies of projects in a repository.

It gives me the peace of mind that what I need for the repo will always be there so I don't have to worry about weird system issues caused because of some kind of runtime manager messing with things without me knowing.

This was what I was looking for for a long time, and I'm glad I finally made the decision to switch. I've heard from friends before that they decided to leave Linux behind because they don't have the time to spend to fix things anymore when they break.

I'm hoping that trade-off is no longer necesary with what NixOS has to offer.