A Beginner’s Guide to the Fundamentals

Basic concepts, components, modules, use cases, and the mental model behind declarative Linux
  1. Part 1 — The Mental Model Behind Declarative Linux
  2. Part 2 — The Nix Language, Nixpkgs, Modules, and Options
  3. Part 3 — The Build Lifecycle, Flakes, and ShellsYou are here

The rebuild lifecycle: build, test, switch, boot

The command nixos-rebuild is the normal bridge between configuration code and an activated NixOS system. Different subcommands let you control how much of the change becomes active.

CommandBeginner interpretation
sudo nixos-rebuild buildBuild the configuration, but do not activate it.
sudo nixos-rebuild testActivate the new configuration for the current boot without making it the default boot generation.
sudo nixos-rebuild switchBuild and activate now, and make the generation the normal running configuration.
sudo nixos-rebuild bootBuild and make it the next boot target without switching the currently running system.
sudo nixos-rebuild switch –rollbackReturn the running system to the previous system generation.
Edit .nixEvaluateBuild/downloadCreate generationActivate

This build-before-activation model is one of NixOS’s strongest operational ideas. A large part of the new system can be prepared without destructively rewriting the current one.

Profiles, generations, and rollback

Profiles are versioned references to environments in the Nix store. Each version is a generation. NixOS uses a system profile for system configurations, which is why successive rebuilds can produce a history of bootable or switchable system generations.

The key idea is not that Nix has an “undo button” for every external effect. Rather, older generated system configurations can remain available, with their old package graphs, service definitions, and configuration artifacts.

  • Good rollback candidates: packages, service definitions, generated configuration files, kernels, many system-level settings.
  • Not automatically rolled back: database contents, files in user home directories, cloud resources, secrets changed outside the configuration, and other mutable external state.

Rollback is powerful, not magical

NixOS can roll back the generated operating-system configuration. You still need backups, database migration discipline, application rollback plans, and state-management procedures.

Flakes and flake.lock: a modern project wrapper, still officially experimental

Flakes provide a standard project entry point named flake.nix, plus an input/output model and a flake.lock file that pins input revisions. They are widely encountered in current Nix projects because they make dependencies and project outputs easier to discover and reproduce.

A simplified flake wrapper around a NixOS configuration.

{
  description = “Beginner NixOS configuration”;

  inputs.nixpkgs.url = “github:NixOS/nixpkgs/nixos-26.05”;

  outputs = { self, nixpkgs, … }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = “x86_64-linux”;
      modules = [ ./configuration.nix ];
    };
  };
}

The flake.lock records the exact revisions of flake inputs. That helps different machines use the same source revisions instead of independently resolving a moving branch.

Important status note

As of August 2026, the official nix.dev documentation still describes flakes as experimental. They are useful and common, but beginners should understand the underlying Nix and module concepts rather than assuming flakes are Nix itself.

Development shells: reproducible tools without “installing everything” globally

Nix is useful even before you configure an entire operating system. A development shell can provide a project-specific set of tools: a compiler, language runtime, formatter, database client, package manager, and environment variables.

A traditional shell.nix-style development environment.

{
  pkgs ? import <nixpkgs> {}
}:
pkgs.mkShell {
  packages = with pkgs; [
    nodejs
    git
    postgresql
  ];
}

With a flake-based project, the same idea is commonly exposed as a devShell and entered with nix develop. The key benefit is isolation by declaration: the project says what it needs, instead of depending on whatever happens to be installed globally on the developer’s workstation.

Binary caches and substituters: why Nix does not compile everything all the time

A common beginner fear is that Nix must build every package from source. Normally it does not. Nix can download exact prebuilt store objects from configured binary caches, called substituters, when suitable signed outputs are available.

Derivation neededCheck storeCheck cacheDownload exact outputBuild only if needed

Teams can also operate private caches. A CI system can build once, publish signed store outputs, and let developer, QA, staging, or production systems reuse those exact artifacts.

Garbage collection: what happens to all those old versions?

Because Nix keeps immutable store objects and generations, old data can accumulate. Nix garbage collection removes store paths that are no longer reachable from a garbage-collector root such as an active profile or another retained reference.

This is an important balance: keep enough generations for useful rollback, but periodically remove unneeded roots and collect unreachable store objects. Treat “delete old generations” and “collect unreferenced objects” as related but conceptually distinct operations.

Beginner safety rule

Do not aggressively garbage-collect on day one. Learn how generations and roots work first, then automate retention deliberately so you do not remove rollback points you expected to keep.

Where NixOS is especially useful

NixOS can be used as a general-purpose Linux distribution, but its advantages become most visible when environment drift, repeatability, multi-machine configuration, or frequent experimentation matter.

Use caseWhy NixOS fits
Developer workstationVersion-controlled packages, services, drivers, shells, and repeatable workstation rebuilds.
WSL development environmentA lightweight but full declaratively managed Linux userland under Windows, useful for matching production tooling more closely.
CI/QA runnersEphemeral or rebuildable workers with pinned toolchains and less configuration drift.
Staging environmentsPromote largely the same modules and package inputs used earlier in the lifecycle.
Production serversReviewable configuration-as-code, atomic system generations, rollback, and binary-cache reuse.
HomelabExcellent for learning infrastructure-as-code and rebuilding machines after experiments.
Specialized GPU/AI systemsPin drivers, CUDA-related packages, runtimes, services, and system configuration together.
Reproducible researchDeclare tool versions and environments so future runs can reconstruct the computational setup more reliably.

A useful architecture picture: NixOS as layers

Beginners often understand NixOS faster when they stop thinking of it as “a package manager with a strange syntax” and instead see a stack of cooperating layers.

LayerResponsibility
Your configurationYour intent: modules, host settings, package choices, service options, environment differences.
NixOS module systemCombines option declarations and definitions into one coherent operating-system configuration.
NixpkgsSupplies packages, package-building functions, modules, libraries, and release branches.
Nix evaluator / build engineEvaluates expressions, identifies derivations and dependencies, builds or substitutes outputs.
Nix storeHolds immutable packages and generated artifacts at unique store paths.
Activation + systemd/LinuxLinks and activates the generated system, starts/stops services, and runs as a normal Linux OS.

What NixOS does not automatically solve

The reproducibility story is strong, but it is easy for newcomers to overgeneralize it. Nix makes many software and system inputs explicit; it does not eliminate every source of variability in computing.

  • Mutable data: databases, uploads, home directories, and application state still need normal data-management and backup practices.
  • Secrets: you should not simply commit production secrets into a world-readable or widely shared Nix configuration. Use a suitable secrets-management approach.
  • Hardware differences: a pinned configuration cannot make different CPUs, GPUs, disks, firmware, or networks physically identical.
  • External services: APIs, SaaS systems, DNS, cloud resources, and remote dependencies can change independently of your local Nix configuration.
  • Build reproducibility limits: a pinned dependency graph improves reproducibility, but true bit-for-bit reproducibility also depends on how individual packages are built and on other relevant inputs.

Common beginner mistakes

MistakeBetter mental model
Editing generated files directlyChange the Nix option or module that generates the file.
Treating /nix/store like /usr/localThe store is managed build output, not a hand-edited software directory.
Putting everything in configuration.nixSplit by concern: base, hardware, users, networking, roles, applications, hosts.
Assuming flakes are requiredThey are a project/input-output convention; learn Nix, Nixpkgs, and modules underneath them.
Confusing package versions with system.stateVersionThey solve different problems; stateVersion preserves compatibility defaults.
Expecting rollback to reverse database migrationsOperating-system generation rollback and application-data rollback are separate disciplines.
Using ad-hoc installs for core system toolsPrefer declarative system configuration when you want the machine state to be reproducible.
Garbage-collecting too aggressivelyRetain deliberate rollback points until you understand profiles and roots.

A practical learning path for your first NixOS machine

You do not need to learn the entire Nix language or Nixpkgs repository before using NixOS. A staged learning path is much easier.

  1. Install NixOS in a disposable VM or other safe environment and keep the generated hardware configuration.
  2. Change one obvious setting such as the hostname or a system package, then run nixos-rebuild switch.
  3. Enable a simple service such as OpenSSH and inspect the relevant NixOS options.
  4. Split one concern into its own module and import it.
  5. Create a second host or VM that reuses a shared module.
  6. Experiment with nixos-rebuild build, test, boot, switch, and rollback so you understand generations before relying on them operationally.
  7. Create a project-specific development shell and compare it with globally installing the same tools.
  8. Only then introduce flakes if they fit your workflow, and inspect what the lock file actually pins.
  9. Put your configuration under version control and treat changes like code: review, test, commit, and promote deliberately.

The best way to learn NixOS

Make small changes, rebuild often, and inspect what changed. Nix becomes much less mysterious once you repeatedly connect one line of configuration with the generated system behavior it causes.

Beginner glossary

TermPlain-English meaning
Attribute setA collection of named values: { name = value; … }. One of the most common Nix structures.
Binary cache / substituterA server that provides prebuilt Nix store objects so your machine can download rather than build them.
ClosureEverything an object depends on, recursively, within the Nix store graph.
DerivationA precise Nix build specification with declared inputs and outputs.
EvaluationThe process of interpreting Nix expressions to determine values, configurations, and build descriptions.
FlakeAn experimental standardized Nix project format with declared inputs/outputs and usually a lock file.
GenerationA version of a profile, such as a versioned NixOS system configuration.
ModuleComposable NixOS configuration logic that declares and/or defines options.
NixpkgsThe main package and NixOS module repository used by the Nix ecosystem.
OptionA typed configuration interface exposed by the NixOS module system.
ProfileA versioned reference to a user or system environment stored in the Nix store.
Store pathAn immutable object path under /nix/store, typically with a hash-derived prefix.
SubstitutionDownloading an already-built store result from a cache instead of building it locally.

Official references and where to go next

Nix changes over time, and the option set is enormous. For authoritative details, use the current official documentation rather than relying on old blog posts or copied snippets.

  • NixOS Manual (current stable): https://nixos.org/manual/nixos/stable/
  • Nix reference manual: https://nix.dev/manual/nix
  • nix.dev – learning and concepts: https://nix.dev/
  • nix.dev – Flakes: https://nix.dev/concepts/flakes.html
  • NixOS package and option search: https://search.nixos.org/

Current reference point

The stable NixOS manual identifies version 26.05 as the current stable release in September 2026. Its documentation describes NixOS as a Linux distribution based on Nix and composed from modules and packages in Nixpkgs. The official nix.dev documentation continues to mark flakes as experimental.