

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.
| Command | Beginner interpretation |
| sudo nixos-rebuild build | Build the configuration, but do not activate it. |
| sudo nixos-rebuild test | Activate the new configuration for the current boot without making it the default boot generation. |
| sudo nixos-rebuild switch | Build and activate now, and make the generation the normal running configuration. |
| sudo nixos-rebuild boot | Build and make it the next boot target without switching the currently running system. |
| sudo nixos-rebuild switch –rollback | Return the running system to the previous system generation. |
| Edit .nix | → | Evaluate | → | Build/download | → | Create generation | → | Activate |
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 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.
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 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.
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.
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 needed | → | Check store | → | Check cache | → | Download exact output | → | Build 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.
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.
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 case | Why NixOS fits |
| Developer workstation | Version-controlled packages, services, drivers, shells, and repeatable workstation rebuilds. |
| WSL development environment | A lightweight but full declaratively managed Linux userland under Windows, useful for matching production tooling more closely. |
| CI/QA runners | Ephemeral or rebuildable workers with pinned toolchains and less configuration drift. |
| Staging environments | Promote largely the same modules and package inputs used earlier in the lifecycle. |
| Production servers | Reviewable configuration-as-code, atomic system generations, rollback, and binary-cache reuse. |
| Homelab | Excellent for learning infrastructure-as-code and rebuilding machines after experiments. |
| Specialized GPU/AI systems | Pin drivers, CUDA-related packages, runtimes, services, and system configuration together. |
| Reproducible research | Declare tool versions and environments so future runs can reconstruct the computational setup more reliably. |
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.
| Layer | Responsibility |
| Your configuration | Your intent: modules, host settings, package choices, service options, environment differences. |
| NixOS module system | Combines option declarations and definitions into one coherent operating-system configuration. |
| Nixpkgs | Supplies packages, package-building functions, modules, libraries, and release branches. |
| Nix evaluator / build engine | Evaluates expressions, identifies derivations and dependencies, builds or substitutes outputs. |
| Nix store | Holds immutable packages and generated artifacts at unique store paths. |
| Activation + systemd/Linux | Links and activates the generated system, starts/stops services, and runs as a normal Linux OS. |
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.
| Mistake | Better mental model |
| Editing generated files directly | Change the Nix option or module that generates the file. |
| Treating /nix/store like /usr/local | The store is managed build output, not a hand-edited software directory. |
| Putting everything in configuration.nix | Split by concern: base, hardware, users, networking, roles, applications, hosts. |
| Assuming flakes are required | They are a project/input-output convention; learn Nix, Nixpkgs, and modules underneath them. |
| Confusing package versions with system.stateVersion | They solve different problems; stateVersion preserves compatibility defaults. |
| Expecting rollback to reverse database migrations | Operating-system generation rollback and application-data rollback are separate disciplines. |
| Using ad-hoc installs for core system tools | Prefer declarative system configuration when you want the machine state to be reproducible. |
| Garbage-collecting too aggressively | Retain deliberate rollback points until you understand profiles and roots. |
You do not need to learn the entire Nix language or Nixpkgs repository before using NixOS. A staged learning path is much easier.
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.
| Term | Plain-English meaning |
| Attribute set | A collection of named values: { name = value; … }. One of the most common Nix structures. |
| Binary cache / substituter | A server that provides prebuilt Nix store objects so your machine can download rather than build them. |
| Closure | Everything an object depends on, recursively, within the Nix store graph. |
| Derivation | A precise Nix build specification with declared inputs and outputs. |
| Evaluation | The process of interpreting Nix expressions to determine values, configurations, and build descriptions. |
| Flake | An experimental standardized Nix project format with declared inputs/outputs and usually a lock file. |
| Generation | A version of a profile, such as a versioned NixOS system configuration. |
| Module | Composable NixOS configuration logic that declares and/or defines options. |
| Nixpkgs | The main package and NixOS module repository used by the Nix ecosystem. |
| Option | A typed configuration interface exposed by the NixOS module system. |
| Profile | A versioned reference to a user or system environment stored in the Nix store. |
| Store path | An immutable object path under /nix/store, typically with a hash-derived prefix. |
| Substitution | Downloading an already-built store result from a cache instead of building it locally. |
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.
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.