Computers as code: Why declarative systems are the future of computing

A stylized photo of a backlit keyboard with multiple overlapping ghostly photos of itself overlayed.
BlogLink to blog
Blog
9 min read

A different way of thinking about how we use and manage computers, in both our personal lives and professional lives. Image by Paul Cook from Pexels https://www.pexels.com/photo/matrix-1780710/


Contents


Introduction 

I’ve been writing about NixOS a lot recently, but for a good reason: NixOS is reshaping the way I see personal computing, and I think it has a lot of potential to change the way people interact with computers in general.

There’s been a lot of disillusionment with how humans use computers today. It’s not just that computers are vehicles for commercial spyware and data hoovering 🔗. It’s not just that computers come bundled with unnecessary, unwanted software 🔗 that’s often impossible to uninstall. It’s not just that computers are constantly under attack from hackers, malware authors, and nation-state actors 🔗.

It’s much simpler than that. We want computers to work a certain way, but getting them to that point is really, really hard.

Let’s look from the perspective of someone who isn’t a software developing, Linux-using geek (I’m using “geek” affably here). People want computers to do certain things: play games, stream music and movies, create and edit documents, etc. It doesn’t matter how the computer manages these tasks, just that it can. Of course, not everyone needs the exact same features—some people are fine without gaming, just like some people are fine without streaming. People have differing wants and needs, unsurprisingly.

Today, operating system developers like Microsoft, Canonical, and Red Hat work through this by creating general-purpose operating systems that have to be tweaked and cajoled into doing what you want. This tweaking and cajoling takes time and a bit of expertise. You need to figure out what software to download, whether it’s compatible with your system, how to install it, where the executables end up, and how to keep it all up to date.

Over time, you’ve got your house-of-cards system set up just the way you like. But if you’re unlucky enough to get hit by malware, or you make a change that makes your system unusable and you need to start over, you need to make these tweaks all over again. Hope you remembered them, or at least wrote them down!

This can’t be the most optimal way to use a computer. There’s got to be a better approach.

Self-building systems 

It’s 6pm on a Friday. Your brand-new laptop just got delivered. You pop open the box, pull out your shiny new Lenasucrosoft, and turn it on. Once it boots, you see a welcome screen with the normal options: choose your time zone, enter a username, choose how you want to install, etc.

But then, a new screen appears with a bunch of different categories: gaming, media, office work, streaming, etc. Each category has a checkmark next to it, and when you click on the category name, a text box appears explaining what each category does to your final system. “Gaming” installs drivers for your video card and installs Steam; “streaming” installs OBS and plugins for streaming to Twitch.tv and YouTube; “office work” installs LibreOffice, Microsoft Teams (the horror! 🙀), and Zoom. Each of these is a module, a set of instructions that tweaks your system in just the right way. You can pick and choose exactly what you want, and the system will make it happen. Rather than build the system up to the desired state, you tell the system the desired state and it builds itself up.

You make your choices, click Next, and go make dinner while the system does its thing. When you get back, it’s set up exactly the way you want. It even saved a little text file to your desktop containing your exact system configuration, from the username and password you picked, to the software categories you selected, to the installation method and disk partitioning scheme you used. You can take this file to any other computer with the same general hardware, boot up an operating system installer, drop the file into the installation program, and get an exact copy of your system.


This type of system already exists, believe it or not. You’ll see it everywhere in cloud computing. Tools like Terraform, Ansible, and Salt Stack are all designed around the idea of systems building themselves up to a desired state. This desired state is usually spelled out in YAML or JSON files, describing how much CPU, memory, or disk space to provision; how to deploy applications; what security rules to enforce, etc. It’s powerful, but way too technical for the average user, so it’s remained fairly contained to the software development industry.

And then there’s NixOS. NixOS pulls this concept closer to regular desktop users by letting you write out (literally) the end state of your system in plain text files, just like Ansible or Terraform. You tell NixOS: “This is how I want my computer to be set up. Make it happen.” Then, you run a single command. Nix (the program powering NixOS) goes and fetches the software you want, installs it, and configures it in exactly the way you described. Even if you completely nuke your computer and start over from scratch, as long as you have those text files defining your system, you can get right back to where you were.

There’s a ton of potential with this system. Not only does it make it way easier to fix a broken system, it makes it way easier to build systems that are ready to go out-of-the-box. To understand how, let’s look at NixOS modules.

How NixOS modules work 

There are two concepts that are key to modularity in Nix and NixOS: modules, and options. A module is a self-contained unit that performs a certain function or provides a certain outcome, and an option is a flag that enables, disables, or changes the behavior of a module.

For example, let’s say we have a “gaming” module that turns a regular NixOS system into a full-on gaming PC. It installs a graphical user interface (GUI), installs drivers for 3D-accelerated video cards, tweaks the system configuration for performance over battery life, and installs gaming platforms like Steam. This gaming module might have an option called enable that turns the module on. Within your NixOS system config, you just add the line gaming.enable = true;, run nixos-rebuild, and in just a few minutes, you have a fully capable gaming PC ready to run any game you want. That’s insane, and it’s not something we see anywhere else in consumer PCs.

This is, of course, an oversimplification. But it’s not too far from the current reality. Projects like nixos-hardware 🔗 are already creating modules to fix the missing pieces in off-the-shelf consumer hardware, and NixOS already has thousands of modules and options 🔗 with more being written by the day. It’s not hard to imagine modules for streaming, for music production, for video editing, or for software development. Under-the-hood, each of these is a complex, arcane set of commands. But to the user, it’s just a few simple lines that can be saved to a text file and copied over a USB drive.

I honestly think the only things holding back NixOS from becoming a major Linux distro is ease of use and familiarity. Because of Windows, so many people are used to the traditional way of starting out with a general purpose OS and having to fiddle with it until it’s the way you want. NixOS also involves fiddling, but the difference is you only need to fiddle once, then you’re done. Forever. Or at least until you choose to change your setup, and even then it’s far less difficult and risky than doing it the old-fashioned way. Plus, NixOS assumes you have a pretty good understanding of the ins-and-outs of Linux. Normal computer users don’t care about Gnome vs. KDE, or PulseAudio vs. Pipewire, or X11 vs. Wayland. They just want their stuff to work.

I think a good starting place would be to have a website to host Nix templates: essentially, pre-made Nix files that take care of the boilerplate stuff for you. New users could just browse templates by screenshot or video, find the one they like, import it into their own NixOS configuration, and rebuild. They can add their own tweaks if they like, but even if they do nothing else, they’ll still have a complete NixOS-powered system without having to frontload all of the little details.

Declarative systems promote collaboration 

There’s another huge benefit to the declarative model that I don’t think gets enough attention: shareability.

In the NixOS community, it’s very common for folks to post their entire system configurations online 🔗 for anyone to see. I host mine right on GitHub 🔗. “But Aires, you devilishly handsome lion, isn’t that a security risk?” You might be asking. And yes, there is the potential for someone to find an extra open port, or a missing firewall, or credentials that you accidentally committed. NixOS has tools to help with this, like sops-nix and agenix. But what this enables is the ability for anyone to write a module that anyone else can use to make their own lives easier.

Let’s take nixos-hardware 🔗 as an example. This is a community-owned and maintained repository with a single goal: fix all the little quirks and gotchas in different computer configurations. Remember that brand-new laptop you just bought? Well, maybe it’s so new that NixOS couldn’t detect a lot of hardware out-of-the-box. As a result, the camera and fingerprint readers don’t work. You can check nixos-hardware to see if your laptop is included. If so, just add its module to your system config, and rebuild. NixOS will fetch the module, patch it into your system, and by the next reboot, your laptop is 100% fully capable and ready to go. It’s the open source community at its absolute best.

There are ways to make this better, of course. I’d love if NixOS could automatically detect and apply the right hardware config for you, just as long as you enabled the nixos-hardware repository. More user-friendliness can only benefit NixOS, as long as it retains the more advanced options for power users.

It takes a village 

I’m not the first person or the only person to think about this, not even in the Nix community. Jake Hamilton started Snowfall 🔗, a set of libraries, modules, and programs for making Nix easier to use. It’s all built on top of the existing Nix language and design, which to me speaks volumes about how powerful and flexible Nix itself is. Plus, if you want to do more advanced things that Snowfall doesn’t support, you can always fall back to writing regular old Nix.

There’s also Lix 🔗, a Nix fork created a few months before this blog post. You’d think a complete Nix replacement would be hard to install, but nope. You just add some lines to your configuration file 🔗, and it gets pulled in seamlessly.

And just now, as I was writing this blog, I learned about Fediversity 🔗, a European Commission-funded project to make self-hosting easier for individuals built on NixOS.

There’s so much cool work already going on in this space, and as NixOS becomes less of a niche distribution and more folks start hacking on it, it’ll only become better. And even if Nix itself crumbles, other projects will almost certainly spring up in its place.

Final thoughts 

This was a bit of a rambly post. I really do think modular, declarative systems like NixOS have the potential to reshape the way we interact with computers. We need to change the approach from “telling the computer what I want it to do” to “telling the computer what I want, and letting it get there on its own.” Today, it starts with Nix files. Tomorrow? Who knows.

Previous: "Why is enabling automatic updates in NixOS so hard?"
atmospheric breaks breakbeat buddhism chicago code disco fediverse fiction funk furry house house music kubernetes lgbt linux logseq mastodon mental health movies music nixos obsidian personal philosophy pkm poetry prompt second life social software soul technology writing