Nix Package Manager

Nix cheatsheet — install packages, use nix-shell for reproducible envs, manage profiles. nix-env -i, nix-shell -p, nix flake, nix run. Full Nix package manager reference.

7 min read

What it is

Nix is a powerful package manager that enables reliable and reproducible builds and deployments across multiple systems, allowing you to install software without interfering with other packages.

Installation

Linux

sh <(curl -L https://nixos.org/install) --daemon

This command downloads and runs the official Nix installation script. The --daemon flag is recommended for system-wide installation. Follow the on-screen prompts for configuration.

macOS

sh <(curl -L https://nixos.org/install)

This command downloads and runs the official Nix installation script for macOS. It installs Nix to /nix by default.

Windows

Nix on Windows is experimental and typically requires WSL (Windows Subsystem for Linux).

  1. Install WSL 2.
  2. Open a WSL distribution (e.g., Ubuntu).
  3. Follow the Linux installation instructions within WSL:
    sh <(curl -L https://nixos.org/install) --daemon
    

Core Concepts

  • Nix Store (/nix/store): All Nix packages and derivations are installed in the Nix store. Each package resides in its own unique directory named by its hash, ensuring isolation and immutability. Example: /nix/store/s0a3f11d84f1b4c30142241d37148232b-hello-2.10.
  • Derivations (.drv files): These are build instructions that Nix executes. They describe how to build a package, including its dependencies, build scripts, and output.
  • Nix Expressions (.nix files): These are Nix language files that define packages, configurations, or entire system environments. They are declarative and reproducible.
  • Nix Language: A purely functional, lazy programming language specifically designed for package management and system configuration.
  • Channels: Mailing lists for Nix package sets. They provide a way to subscribe to updated sets of packages. nixos-unstable, nixos-23.11 are examples.
  • Nixpkgs: The main repository containing Nix expressions for a vast collection of software.

Commands / Usage

Managing Packages

  • Search for packages:

    nix search nixpkgs firefox
    

    Searches the configured Nix channels for packages matching "firefox".

  • Install a package (imperative, not recommended for reproducibility):

    nix-env -iA nixpkgs.hello
    

    Installs the hello package from the nixpkgs channel into your user profile.

  • Install multiple packages:

    nix-env -iA nixpkgs.git nixpkgs.htop
    

    Installs both git and htop into your user profile.

  • Upgrade packages:

    nix-env -u
    

    Upgrades all packages in your user profile to the latest versions available in your channels.

  • Upgrade specific packages:

    nix-env -uA nixpkgs.firefox
    

    Upgrades the firefox package in your user profile.

  • List installed packages:

    nix-env -q
    

    Lists all packages currently installed in your user profile.

  • Uninstall a package:

    nix-env -e hello
    

    Removes the hello package from your user profile.

  • Rollback profile changes:

    nix-env --rollback
    

    Reverts your user profile to the previous generation.

  • List profile generations:

    nix-env --list-generations
    

    Shows a history of your user profile states, allowing you to switch between them.

  • Switch to a specific profile generation:

    nix-env --switch-generation 5
    

    Switches your user profile to generation 5.

Managing Nix Channels

  • Add a channel:

    nix-channel --add https://nixos.org/channels/nixos-unstable nixpkgs
    

    Adds the nixos-unstable channel and names it nixpkgs.

  • Update channels:

    nix-channel --update
    

    Fetches the latest package definitions from all subscribed channels.

  • List subscribed channels:

    nix-channel --list
    

    Shows all currently subscribed Nix channels.

Building and Managing Nix Expressions

  • Build a Nix expression (e.g., a package definition):

    nix-build '<nixpkgs>' -A hello
    

    Builds the hello package from your Nixpkgs. The result is a symbolic link named result in the current directory pointing to the package in the Nix store.

  • Build a specific Nix expression file:

    nix-build ./my-package.nix
    

    Builds the package defined in my-package.nix.

  • Enter a shell with a package available:

    nix-shell -p hello
    

    Starts an interactive shell where the hello package is available in the PATH.

  • Enter a shell with multiple packages:

    nix-shell -p git htop nodejs
    

    Starts an interactive shell with git, htop, and nodejs available.

  • Enter a shell defined by a Nix expression:

    nix-shell ./shell.nix
    

    Starts an interactive shell based on the environment defined in shell.nix.

  • Build an environment from a Nix expression (e.g., for deployment):

    nix-build --out-link ./my-deployment -E 'with import <nixpkgs> {}; runCommand "my-env" {} "mkdir -p $out/bin && cp $(cat pkgs.txt | xargs -I{} nix-build -A {} --no-out-link)/bin/* $out/bin"' --arg pkgs "{ hello = pkgs.hello; }"
    

    This is a more complex example demonstrating how to build a specific environment. A more common approach for reproducible environments is using nix-shell or NixOS configurations.

  • Evaluate a Nix expression:

    nix-instantiate --eval --json '<nixpkgs>' -A hello
    

    Evaluates the Nix expression for the hello package and prints its resulting Nix store path in JSON format.

  • Run a command with specific packages:

    nix-run -iA nixpkgs.cowsay 'cowsay "Hello Nix!"'
    

    Runs the cowsay command with the cowsay package available.

Garbage Collection (Cleaning the Nix Store)

  • Delete unreferenced store paths:

    nix-collect-garbage
    

    Removes store paths that are no longer referenced by any garbage collection roots (e.g., user profiles, NixOS configurations).

  • Delete old profile generations:

    nix-collect-garbage -d
    

    Deletes all but the latest generation of each profile, in addition to unreferenced store paths.

  • Delete unreferenced paths and old generations:

    nix-collect-garbage --delete-old
    

    Removes all but the current generation of profiles and unreferenced store paths.

NixOS Specific (if using NixOS)

  • Rebuild NixOS system configuration:

    sudo nixos-rebuild switch
    

    Builds and activates the system configuration defined in /etc/nixos/configuration.nix.

  • Test NixOS system configuration:

    sudo nixos-rebuild build
    

    Builds the system configuration without activating it, allowing you to test the build.

  • Rollback NixOS system configuration:

    sudo nixos-rebuild switch --rollback
    

    Reverts the system to the previous configuration generation.

  • Boot into a previous NixOS generation: This is typically done via the bootloader menu (GRUB).

Common Patterns

  • Reproducible development environment: Create a shell.nix file:

    { pkgs ? import <nixpkgs> {} }:
    
    pkgs.mkShell {
      buildInputs = [
        pkgs.git
        pkgs.nodejs-18_x
        pkgs.yarn
      ];
    
      shellHook = ''
        echo "Welcome to the reproducible development shell!"
        export MY_VAR="Hello from Nix!"
      '';
    }
    

    Then run nix-shell in the same directory to enter an environment with git, nodejs-18_x, and yarn available.

  • Installing a package without modifying your user profile:

    nix-shell -p python3Packages.requests
    

    This opens a shell where python3Packages.requests is available. You can then run Python scripts that use this library.

  • Building a project with specific dependencies:

    nix-build '<nixpkgs>' -A python3Packages.buildPythonApplication '{ buildInputs = [ python3Packages.requests ]; src = ./.; installPhase = ''
        mkdir -p $out/lib/python3.11/site-packages
        cp -r $(echo ${python3Packages.requests}/lib/python3.11/site-packages/*) $out/lib/python3.11/site-packages/
        cp my_script.py $out/bin/
      ''; }'
    

    This example is illustrative; real package building is more complex and often uses mkDerivation.

  • Downloading a package’s source code:

    nix-prefetch-url --unpack https://example.com/my-package-1.0.tar.gz
    

    Downloads and unpacks the source code for a given URL.

  • Finding the Nix store path of an installed package:

    nix-env -q --out-path hello
    

    Outputs the Nix store path for the hello package in your profile.

  • Composing package sets:

    # In a .nix file
    let
      commonPkgs = import <nixpkgs> { overlays = []; };
      devPkgs = import <nixpkgs> { overlays = [ (self: super: { my-tool = super.callPackage ./my-tool.nix {}; }) ]; };
    in
    devPkgs.my-tool
    

    This shows how to create custom package sets or override existing ones.

Gotchas

  • Imperative vs. Declarative: Using nix-env -i is imperative and creates a user profile that is not easily reproducible. For reproducible environments, prefer nix-shell with shell.nix or NixOS configurations.
  • Channel Updates: nix-channel --update only updates the metadata about packages. To actually install or build newer versions, you need to use nix-env -u or rebuild your Nix expression.
  • Garbage Collection: Nix does not automatically delete old or unreferenced packages. You must run nix-collect-garbage periodically to reclaim disk space.
  • Nix Store Path Hashing: The hash in Nix store paths is derived from the package’s dependencies, build instructions, and source. Changing any of these results in a new, distinct path, ensuring immutability.
  • Build Failures: If a build fails, Nix will report the error. Debugging often involves entering the build environment using nix-build --keep-failed and then nix-shell on the resulting .drv file to manually inspect and fix the build script.
  • Nix Language Learning Curve: The Nix language is functional and can be unfamiliar. Many common patterns are available in Nixpkgs’ lib module, but writing complex custom derivations might require learning more about the language.
  • Symlinks in /run/current-system on NixOS: On NixOS, /run/current-system is a symlink to the current system generation in /nix/store. Do not modify files directly within /run/current-system; instead, modify your configuration.nix.