# What is Nix?
Table of Contents
I’m old. I’ve been into tech most of my life, and professionally I’ve been doing this for more than 20 years. Bearing this in mind, even with recent tech developments, I can say Nix is the most exciting technology I’ve come across in my life. It is a thing of beauty. I realise these words do not help inform you of what Nix is. Let me try again…
For me, Nix solves a specific problem that I’ve always had: that initial setup when you just want to get some work done.
Want to try out a new tool such as ghostty, but don’t want to mess up your system with an install you’ll forget about in a week? With Nix, just type nix-shell -p ghostty. Nix will install the package, and all its dependencies in a temporary system folder. You can launch it, quit it, and forget about it. Not impressed? Try nix-shell -p blender.
Nix is an expression language that allows you to declaratively define a development environment. You can specify the tools needed (such as just, neovim, or gh), the language needed go, rust etc). You can specify the environment variables needed. You can specify the secrets needed. You can run custom steps or scripts upon creating the development environment. You can commit all of this into your application’s git repo, so that other Nix users can use the exact same environment.
If you want to get really advanced, you can use Nix in your CI build runners, where they too can use the same development environment.
“Builds on my machine” isn’t such a pointless statement with Nix.
How this started for me
I’ve been a Linux user - well, tourist really - for many years. I started with Red Hat and SUSE in the late 90s, then took a break for a little while when I got Macs at home. They seemed to scratch my Linux itch. Then around 14 years ago, I started getting into it again, around the time Ubuntu started gaining in popularity.
Most bank holidays, I would typically do one of two things. One is, I would install some distro or another on one of my old Macs (Intel based), as they were no longer supported by Apple. I’d be one of those distro-hoppers. I tried Ubuntu (obvs), ElementaryOS, PopOS. I think I briefly tried CentOS too. I wasn’t just distro-hopping. I was genuinely trying to find a system I could call “home”.
System entropy
Something always happened with my distros though, no matter which one I went for. I’d start by installing various tools I liked, or that I’d come across and wanted to try. I’d install the languages, and dev tools. Then after a few months, I’d forget which ones I have, or I’d struggle with keeping them up to date. Eventually, the system would just feel “messy” to me, and I’d wait till the next bank holiday to try something else, then the cycle would start again.
NixOS solves this by enabling you to define the whole system declaratively using its own expression language. Not only that though. Have you ever installed a tool or plugin that rendered your system unbootable? I certainly have. With NixOS though, if that were to happen, you can boot your system into a previous configuration setting. NixOS calls these “generations”.
What you end up with is an incredibly robust system. I’m pretty sure you’ve never had one of those before. I hadn’t.
Learning a new language / framework
The other bank holiday activity that I would do (and still do) is taking the time to learn a new language or framework. Again though, the holiday would typically end up feeling wasted, as I’d spend most of the time setting up my development environment. It takes a good few hours to get the right tools (and versions!), the language, the IDE setup, everything. By the time you have it setup, your enthusiasm has waned considerably. Not these days though. Not since Nix.
Taking the plunge
Somewhere along the way, I started hearing about a Linux distro that was fully declarative. I thought very little of it at first, as I figured it would be a barely complete implementation, and would feel like it’s stuck together with blu-tack.
Then I started to hear that it had a steep learning curve, and this puts people off. It put me off too, but the name kept popping up, and one day I just decided to try it.
The bad news is, yes there is a learning curve. The good news though is you can get a surprising amount of use out of very little learning. You will be pleasantly surprised I feel. Also the learning curve has been somewhat exaggerated I feel.
Nix, Nixpkgs, NixOS
Nix is really 3 separate things: Nix (the expression language), Nixpkgs (the package manager), and NixOS (the operating system). If you’re on a Mac or Linux, you can just use the package manager if you just want to dip your toes in. I didn’t know this would offer as much as it does, so I chose to use the full OS instead. I don’t regret a thing mind you, as it solved the entropy issue I was experiencing.
As a teaser for how convenient it is to create a development environment, here’s an example of an early shell.nix file I’d created for Python projects. Notice the github URL at the top - that’s pointing to a branch on the nixpkgs repo. This is the source of the packages I pull in below that. The shellhook at the end echoes out a message when the development shell is created. I was a big fan of cowsay and lolcat at the beginning. It looks cool.
{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11") {} }:
pkgs.mkShellNoCC { packages = with pkgs; [ (python3.withPackages (ps: [ ps.pip ps.pipx ps.pytest ps.coverage ])) poetry curl jq ];
MESSAGE = "Python!"; shellHook = '' echo $MESSAGE | cowsay | lolcat '';}Further reading, and a few hints & tips
If you want to know more, a good place to start is the Nix main site itself.
- https://nixos.org/ - the main homepage. Check out the examples further down the home page to get some terrific examples of Nix goodness
- https://search.nixos.org/packages - search through the whole package repo
I will be posting some tutorials etc on this site at various points, which hopefully will help new starters in particular.
Hints & tips
Here are some things I wish I’d known at the start:
Start with nixpkgs if you just want to dip your toes in
This will give you declarative development environments and ephemeral package installs. You won’t get the declarative system configs, but that also means you won’t have to get into the whole nix config setup etc.
Embrace flakes early
Flakes are classed as experimental, but they are so essential by this point that they may as well be classed as the preferred way.
As for what they are…that’s tricky to describe. Here are some of the benefits:
- They facilitate fully reproducible environments
- They enable you to store and define your system configs in a dedicated git repository, and easily apply those configs to your system
- They make it easy to turn a git repository into a Nix ingestible app / tool etc.
You’ll likely put flakes off for quite a while, until you get used to Nix. However, a lot of the issues you might have with Nix in the beginning are solved by flakes. Specifically the ability to store you system configs in a git repo and easily apply them.
LLMs can be very useful at navigating the Nix landscape. However, try not to depend on them too much, as it will slow down your learning of the Nix expression language. It isn’t so hard to get to grips with, especially for the simpler configs. I’ve experimented with them a lot here, and will blog about that at some point too.
What’s next?
By now, I’ve been using NixOS and Nix for about 3 years now, and I’m very comfortable with it. By the end of last year, I’d installed it on 4 machines, as well as my work PC (using WSL), and I’d been experimenting with some of my machines as CI/CD servers.
What I really wanted to know was, can NixOS be used in a production environment? And if so, what would that even look like?
That’s what’s coming next…