Nix is a next-generation package and system manager.
Many other package managers suffer from dependency conflict issues, and many systems built on them 'decay' over time, becoming messier, slower, and more prone to crashes over time. Nix does not suffer from these issues, because of a few unique properties:
- Deterministic: Building the same thing in Nix with the same configuration always results in the same output. No matter where you build it, what else is installed, or how you've configured your system. If it works in one place, it works everywhere; if it breaks in one place, it breaks everywhere in exactly the same way. Say goodbye to "works on my system".
- Isolated: Every package has its own fully-declared set of dependencies, that doesn't conflict with any other package on the system. Dependencies are deduplicated where possible, but it's completely possible to have an unlimited amount of different versions of the same dependency, used by different applications - without dependency conflicts.
- Customizable: All packages can be freely modified, right from within your system configuration, without needing complex custom repository infrastructure or tooling. That includes making patches to dependencies, even for a single application, without affecting anything else on the system! Even packaging your own applications is trivial.
- End-to-end: 'Packages' aren't just software. Nix can build your system configuration, too, with all of the same guarantees, and it can seamlessly extend to container or even multi-system management - whether it's synchronizing the software on your desktop and your laptop, or managing a large fleet of production servers.
- No overhead: Best of all, Nix can do all of the above without needing VMs or containers. That means that there's no runtime overhead, and it works absolutely fine in graphical environments like on a desktop or laptop, too! You can use VMs or containers, of course, where you need them - they're just a part of your system configuration.
^^^todo Add 'derived from a single config file' to the list. ^^^
These properties give you a lot of nice features:
- Reliability: A Nix-based system is much more reliable than what you could get from another Linux distribution (that isn't based on the Nix model). Mystery failures are eliminated, problems are easier to diagnose, and they can be reliably reproduced by people helping you out, even if they are running a totally different system configuration.
- Rollbacks: Change your kernel settings? Install some experimental drivers or software? No problem. If something breaks, you can just roll back to a previous version of your system - even if your system doesn't boot anymore.
- Ease of installation: No need to resolve dependency conflicts, or mess around with
virtualenv
, or pick between two pieces of software that require different conflicting dependencies. Software just works. Even if it's ancient software that requires ancient dependency versions to run that are supported by nothing else, you can make it work without breaking any other software. - Easy synchronization: Synchronizing software or system configurations between computers is as simple as copying over your
configuration.nix
, either manually or through something like Git or even Dropbox. Since the entire system is built from that file, you can apply it to any amount of computers without issues, even if they were running a totally different configuration before. - No 'cruft' or 'decay': Because your system state is derived entirely from the configuration you give it, and not from piecemeal "change this, change that" instructions, your system doesn't accumulate 'cruft' over time like you may be used to from other distributions. A 5-year-old NixOS installation will run just as smoothly and reliably as a 2-day-old one, because effectively every configuration change is a (fast) reinstallation.
- Automated package testing: Because all builds are isolated and deterministic, it's possible to do fully automated package tests, to verify that a package really works as advertised. This is done for the official package set, too.
^^^todo Explain more about NixOS' automated testing setup. ^^^
The properties above are not entirely without tradeoffs - make sure to read the FAQ entry about the tradeoffs before diving into Nix and NixOS.
Confusingly, the name "Nix" is not just used for the package manager, but also for the language that you use to write packages or system configurations. Sometimes, people call it 'nix-lang' to differentiate it from the package manager, and we'll do the same in this documentation.
nix-lang is a little different from what you might be used to. It's a bit like a declarative language such as JSON, but also a bit like a 'real' programming language, with support for functions and variables (sort of). An excellent step-by-step introduction to the language can be found here - it's a fairly simple language, but because it has some unusual characteristics, you should definitely give that a read.
This language is used throughout Nix, and in all of the tooling surrounding it. It's the language you use for writing package definitions, modifying your system configuration, managing multiple servers, and even for writing package tests. Because it allows creating functions and other abstractions, it can support configuration at any scale, without becoming complex to use for the simple cases.
If you're curious why Nix has its own custom language, and why it doesn't just use something that already exists, have a look in the FAQ.
You'll often run across the name 'nixpkgs' in this documentation. Nix itself is really just the package manager and build tool - it doesn't come with any software packages, and expects the user to point it at some sort of 'package set'.
That's where nixpkgs comes in - it's the officially maintained package set for Nix, and it's what almost every Nix user uses. It contains a wide selection of software - comparable to what you might find in most Linux distributions, and sometimes even exceeding them - as well as all the bits and pieces for NixOS (explained below).
You're not limited to using nixpkgs, of course. It's just selected as a default when you install Nix, and you're free to add other package sets, or write an 'overlay' that extends nixpkgs with additional packages. For example, Mozilla maintains a nixpkgs overlay for their Rust and Firefox projects.
If you're in a more experimental mood, you could even totally remove nixpkgs, and write your own package set from scratch. This is something that most users won't want (or need) to do, though.
While Nix can run as a stand-alone package manager on any Linux system, and even on macOS, there's only so much that it can do without control over the rest of the system. NixOS is a Linux distribution that takes the concept of Nix a step further, by making it possible to use Nix for managing your entire system - from software, to services, to kernel settings, to container management, all using the same language.
This documentation is for both Nix and NixOS - NixOS-specific sections will be marked as such.
Nix (and NixOS) themselves only manage a single machine. If you want to manage multiple machines, especially if they are many servers, you can use a tool like NixOps - it's an 'orchestration tool' like Ansible, Chef, or Puppet, but with the guarantees of Nix. Like all of the other tools, you use nix-lang for specifying your systems.
If you're curious about what NixOS with NixOps does better than other orchestration tools, give this excellent article a read.
Hydra is, more or less, a build server. Unsurprisingly, it uses Nix and nix-lang for specifying what to build. It's used to build the binary packages for nixpkgs, for example, as well as for running automated tests to ensure that packages actually work. If you're just using Nix or NixOS as an end user, you probably don't need to care about this.
Because Hydra supports deployment operations after a successful build-and-testing cycle, you could also technically consider it a Continuous Deployment system.