Nix ecosystem (NixOS, nixpkgs, nix-darwin)
Think in layers: Nix language evaluates expressions into derivations, which build into store paths. Everything else -- NixOS, nix-darwin, Home Manager, flakes -- is configuration that produces derivations.
Reference files
| Topic | File | When to read |
|---|---|---|
| nix-darwin (macOS) | reference/nix-darwin.md | macOS system config, darwin-rebuild, Homebrew casks, launchd, Home Manager on macOS |
| Nixpkgs maintainers | reference/maintainers.md | PR workflow, OfBorg, merge bot, nixpkgs-review, r-ryantm, staging, backports, review norms |
| Derivations and packaging | reference/derivations.md | stdenv.mkDerivation, pkgs/by-name, fetchers, language builders, meta, cross-compilation |
| Security | reference/security.md | Hardened profile, firewall, AppArmor, systemd sandboxing, secrets (sops-nix, agenix), secure boot |
| Module system and modularity | reference/modularity.md | NixOS/nix-darwin modules, mkOption, overlays, specialArgs, shared modules, anti-patterns |
| Flakes | reference/flakes.md | Flake anatomy, follows, outputs, flake-parts, dev shells, ecosystem tools, Nix vs Lix, release channels |
| Community and governance | reference/community.md | Communication channels, RFC process, release schedule, documentation hubs, reporting security issues |
Read the relevant reference before giving version-specific flags, option names, or configuration snippets. Prefer the user's NixOS/nixpkgs version when answers differ across releases.
Mental model
Nix language
|
evaluates to
|
derivations
/ | \
NixOS nix-darwin standalone
| | |
nixos-rebuild darwin-rebuild nix build / nix develop
| | |
/etc/nixos flake.nix flake.nix
\ | /
\ | /
nixpkgs (package set)
|
Home Manager (user env, any host)- Nix (or Lix): the language and package manager. Evaluates
.nixfiles into derivations. Lix is a compatible fork; both are supported by nix-darwin and NixOS. - nixpkgs: the package repository (100k+ packages). Provides
stdenv, builders, NixOS modules, and library functions. - NixOS: a Linux distribution configured entirely through Nix modules. Config lives in
/etc/nixos/or a flake. Applied withnixos-rebuild switch. - nix-darwin: the macOS equivalent of NixOS. Manages system settings, services, Homebrew, and launchd through Nix modules. Applied with
darwin-rebuild switch. - Home Manager: user-level environment management. Works standalone or as a module inside NixOS/nix-darwin. Manages dotfiles, shell config, user services.
- Flakes: the input/output schema for reproducible Nix projects. Pins dependencies via
flake.lock. Still marked experimental in upstream Nix but universally adopted.
Red flags (stop and verify)
- Guessing attribute names, option names, or builder arguments instead of checking docs or evaluating locally.
- Pushing untested changes that break nixpkgs evaluation (blocks OfBorg and Hydra for all PRs).
- Targeting the wrong branch (
stagingvsmastervsrelease-YY.MM). - Using
with pkgs;at the top of a file (pollutes scope, hides where names come from). - Using
rec {}wherelet... inwould suffice (rec introduces subtle evaluation issues). - Using
<nixpkgs>lookup paths in flake-based setups (breaks reproducibility). - Placing overlays inside
home.nixwhen Home Manager runs withuseGlobalPkgs = true(overlays are silently ignored; they belong in the host system config). - Baking secrets into the Nix store (store paths are world-readable).
- Assuming
nix-darwinmodules and NixOS modules are interchangeable (they share patterns but have different option trees).
Principles
Reproducibility
Pin all inputs. Use flake locks or fixed hashes. Avoid mutable state (nix-channel, <nixpkgs>, builtins.fetchTarball without hash). The same config on the same inputs must produce the same system.
Declarative configuration
Describe the desired state, not imperative steps. Prefer NixOS/nix-darwin module options over post-activation scripts. If an option does not exist, write a module rather than a shell script.
Modularity
Split configuration by concern. Each module declares its options and activates conditionally (lib.mkIf cfg.enable). Compose modules through imports and specialArgs. Share modules across NixOS and nix-darwin where the option trees overlap.
Security first
Use the hardened profile as a baseline. Manage secrets with sops-nix or agenix, never plain text in the store. Sandbox services with systemd options. Pin and audit dependencies. See reference/security.md.
Minimal rebuilds
Understand the rebuild cost of changes. Layer cache-friendly operations. Use nixos-rebuild build or darwin-rebuild build to test before switching. For nixpkgs PRs, check rebuild counts before choosing master vs staging.
Quick task map
| Task | Where to look |
|---|---|
| Package new software for nixpkgs | reference/derivations.md |
| Configure a NixOS system | reference/modularity.md, reference/flakes.md |
| Configure macOS with nix-darwin | reference/nix-darwin.md |
| Harden a NixOS system | reference/security.md |
| Review or merge a nixpkgs PR | reference/maintainers.md |
| Set up a flake-based project | reference/flakes.md |
| Write a NixOS/nix-darwin module | reference/modularity.md |
| Manage user dotfiles | Home Manager docs + reference/modularity.md (overlay scope) |
| Manage secrets | reference/security.md |
| Find community help or report issues | reference/community.md |
| Understand release channels and branches | reference/flakes.md, reference/community.md |
Workflow: packaging for nixpkgs
- Determine the build system (autotools, cmake, cargo, go modules, npm, python setuptools/poetry, etc.).
- Choose the right builder (
stdenv.mkDerivation,buildRustPackage,buildGoModule,buildNpmPackage,buildPythonPackage). - Place the package in
pkgs/by-name/${shard}/${name}/package.nix(RFC 140). - Add yourself to
maintainers/maintainer-list.nixif not already there (separate commit). - Fill in
metawithdescription,homepage,license,maintainers,platforms, andmainProgram. - Run
nix-build -A <attr>locally; runnixpkgs-review wipto catch dependent breakage. - Open PR against
master(orstagingif rebuild count > 500).
See reference/derivations.md and reference/maintainers.md.
Workflow: system configuration (NixOS or nix-darwin)
- Initialize a flake with
nixosConfigurationsordarwinConfigurations. - Structure modules by feature (networking, desktop, services, users).
- Use
specialArgs = {inherit inputs;}to pass flake inputs into modules. - Apply overlays at the system level (
nixpkgs.overlays), not inside Home Manager whenuseGlobalPkgs = true. - Manage secrets with sops-nix or agenix -- never commit plaintext secrets.
- Build first (
nixos-rebuild build/darwin-rebuild build), then switch. - Pin nixpkgs to a release branch (
nixos-25.11) for stability, ornixpkgs-unstablefor latest packages.
See reference/flakes.md, reference/modularity.md, and reference/nix-darwin.md.
Workflow: reviewing a nixpkgs PR
- Check the target branch (
master,staging,release-YY.MM). - Read the diff for correctness, meta completeness, and commit message convention.
- Run
nixpkgs-review pr <NUMBER>to build affected packages locally. - If OfBorg has not built, trigger with
@ofborg build attr1 attr2(one command per line). - For
pkgs/by-namechanges by a maintainer: consider@NixOS/nixpkgs-merge-bot merge. - Give maintainers roughly one week before merging changes they have not endorsed.