
What is Nix?
Imagine you’re setting up a software environment. You need Git, NodeJS, VS Code, Angular, and a few more libraries. You install them on your desktop machine.
A month later you buy an awesome new laptop. You need to set up the same development environment as your desktop. Through memory alone, you start to install everything. Later you pull down your GitHub repo, and when trying to build, you realize you forgot a couple tools, and the tools you did install are a different version.
Now consider the alternative: imagine a tool where you describe exactly what you need in your environment: NodeJS, VS Code, everything. And you take it a step further and include versions. And that tool installs all the software for you, right down to the same version. In other words, you’ll describe an environment such that it’s identical every time you install it. No version mismatches at all, no forgotten tools.
That’s what Nix is. It’s an entire programming language meant for describing environments so they turn out identical each time.
The language is declarative. What does that mean? “Declarative” means you describe what something looks like, rather than how to do it. I like to use HTML as a great example of a declarative programming language. You put a button on the screen by a simple “button” element, as opposed to a bunch of code drawing the button’s image on each individual pixel and listening for mouse clicks that happen over each of those pixels.
A declarative language simply describes what you ultimately want, as opposed to imperative languages like Python or C++.
Declarative means you describe what you want, the state you expect.
Imperative, on the other hand, means you list the steps to make that state happen.
Most of us are used to telling the computer what to do and in what order: “I just bought a new computer, so I need to install NodeJS, and then the Angular tools…” And invariably we run into: “Oh crap, I ended up with a different version of Node and a different version of Angular!” That’s “imperative,” where we do the steps manually.
But with “declarative” we describe the end goal: “Give me Node version 26.8.1 and Angular version 22.1.4.” And then the tool you’re using figures out how to obtain exactly those versions and start a development environment in your terminal with those versions available. That’s what Nix is.
So imagine you pull a repo down from GitHub. And in that repo is a file describing the environment like I just said. Now presently you don’t have the exact tools installed on your computer. You might have a different version of node, and no Angular at all. That’s okay! With a simple command:
nix develop
Suddenly all those tools are available on your path. You type:
node --version
And you see exactly 26.8.1, not the version you had previously installed. And the “ng” angular tools are there too, along with everything else the repo needs.
Then you open up another terminal, pull down a different repo, requiring a different set of tools. Maybe this is a Python project, needing a particular version of Python and several libraries. Again, no problem! You type
nix develop
and now all the tools and their correct versions are available.
What we have here is the concept of “isolation”. Suppose you pull two repos, and both use NodeJS, but different versions. Nix lets you open up two terminals and have each of them load a different required version of Node.
And ultimately you can have an environment that’s identical to what the repo maintainers have on their system, meaning the environments are reproducible.
Three Pillars of Nix
And that brings us to the three pillars of Nix:
- Declarative: You don’t need to write a bunch of code in the form of steps; you simply describe what the environment looks like
- Reproducible: Every time you run nix, you get exactly the same environment, meaning the same tools and the same versions of those tools
- Isolated: two different environments running at the same time on your computer can have two different versions of the same tool.
By the way, in order to accomplish that third pillar, isolation, Nix maintains its own place on your drive called a “store” where it maintains separate directories (folders) for each version of each tool. So as you require different versions of NodeJS, it will create a new directory and install that version for you. (But in order to use the tools, you don’t really even need to be aware of the store.)
Nix for Everyday Users and NixOS
But let’s take this beyond just developers! Imagine a business with a dozen employees, all of whom need the same software configuration on their computers, including the same versions of said software.
While you could manually install the software on each computer, there’s an easier way: Nix. Nix isn’t just for developers. It can handle entire software configurations for end users, making sure each computer not only has the same software, but the same versions of the software.
Now Nix can exist as a piece of software on each machine; or you can use a Linux-based operating system called NixOS to manage all these computers. NixOS is a complete operating system based on Nix where you can declare exactly what software and versions of said software to install on each machine.
This makes NixOS the ideal operating system for any company, large or small, that needs all its computers to be identical.
Oh and did one of your vendors release a new version of their software? No problem! Update the configuration file.
This is important to understand! Nix monitors the configuration files, and if it detects a change (such as adding software or even removing software or changing a version) it will immediately update the environment to match what’s in the file!
(For a case study, look at what Doctors Without Borders did: https://numtide.com/blog/case-study-doctors-without-borders-medecins-sans-frontieres-nixos/ )
This is the first piece in my own documentation for Nix and NixOS. Why am I doing this? Because the current documentation for Nix SUCKS.
The current documentation is written for people who already know Nix. What good is that?
The current documentation always says, “If you know Haskell, this will make sense…” (that’s a programming language)… but they never cover the situation if you don’t already know Haskell!
Until Nix improves its documentation, it’s going to stall. Nix is an amazing thing and should rank as high as Docker. There’s almost no reason any development team shouldn’t be using it.
So why isn’t that the case? Two reasons:
- The documentation sucks.
- The language is incredibly difficult (too difficult!) to learn.
My goal is to change that! I’m building my own, independent documentation. And as a great teacher, I’m determined to teach it in a way that, FINALLY makes sense.
So I hope this first article helped. Because there’s more to come!