Skip to content

Lesson 01 — What is Nix

The Core Idea

Nix is a purely functional package manager and build system. The word "purely functional" means the same inputs always produce the same output, and there are no side effects. Every package is built in isolation with its exact dependencies, and the result is stored under a unique hash in /nix/store.

Coming from traditional Linux: think of it like a version manager (like nvm or pyenv) but for every piece of software on the system, applied consistently.

The Nix Store

/nix/store/a3k7j2...abc-firefox-125.0/
/nix/store/f9b3c1...def-firefox-124.0/

Both versions coexist. Nothing is mutated. A "broken update" can never leave your system in a half-upgraded state. Rollback is trivially safe.

This is fundamentally different from a traditional distro where apt upgrade modifies files in place under /usr.

Three Things Called "Nix"

People use the word to mean different things depending on context:

Term What it is
Nix language A lazy, purely functional expression language used to describe packages and configurations
Nix package manager The tool that evaluates Nix expressions and builds/installs software
NixOS A Linux distribution where the entire OS is configured with Nix

Nix Language Basics

Nix files are .nix files. The language is declarative — you describe what you want, not the steps to get there.

A simple attribute set (like a dictionary/map):

{
  username = "marcus";
  editor = "neovim";
  enableFirewall = true;
}

A function (everything in Nix is an expression, functions are first-class):

# Takes an attribute set with pkgs, returns a derivation
{ pkgs }:
pkgs.stdenv.mkDerivation {
  name = "hello";
  src = ./src;
}

The let ... in pattern (bind variables locally):

let
  greeting = "hello";
  name = "marcus";
in
"${greeting}, ${name}!"

Derivations — The Fundamental Unit

A derivation is the blueprint for building one thing: a package, a config file, a script. Nix evaluates your .nix files to produce derivations, then realises them (actually builds them).

You rarely write raw derivations. You use helpers like pkgs.stdenv.mkDerivation, pkgs.writeShellApplication, etc.

Key Mental Models from Traditional Linux

Traditional Linux Nix equivalent
/etc/ config files edited by hand Nix modules declaring desired state
apt install foo environment.systemPackages = [ pkgs.foo ]
/usr/local/bin scripts pkgs.writeShellApplication in a module
Upgrade and pray nixos-rebuild test → check → switch or rollback
~/.bashrc by hand Home Manager programs.bash module

What NixOS Adds

NixOS takes the Nix package manager and uses it to configure the entire OS declaratively:

  • Boot loader (/boot/grub.cfg or systemd-boot generated from Nix)
  • Services (systemd units generated from Nix module options)
  • Users and groups
  • Network configuration
  • Kernel parameters

The entire system is described in Nix and rebuilt atomically. If the new config fails to boot, GRUB/systemd-boot shows the previous generation.

Further Reading

  • Zero to Nix — modern opinionated guide, best place to start in 2025+
  • Nix Pills — classic bottom-up series from 2014, still valuable for understanding internals. The preface page has a confusing self-referential notice — skip it and go straight to chapter 1.
  • NixOS Manual — the official reference