Skip to content

Profile

Overview

A profile is a named, mutable view into the Nix store: a directory of symlinks to store paths that represents an active package set or environment. Profiles live outside the store in a profiles directory—typically /nix/var/nix/profiles/ (or $XDG_STATE_HOME/nix/profiles when useXDGBaseDirectories is enabled). ~/.nix-profile is usually a symlink to the current user profile so shells can put ~/.nix-profile/bin on PATH.

Each install, upgrade, or remove appends a numbered generation. The profile name points at profile-N-link, which points at that generation’s store path; older generations stay on disk for rollback. Active and historical profile links are GC roots, keeping their closures reachable until you delete those generations or collect garbage.

This page covers on-disk profile layout, types, and GC roots. Rollback semantics are in Generation; store path identity in Store path; NixOS boot and system rebuilds in Generations and boot.

Details

Layout

Nix keeps profile metadata under the state directory. With default paths, user profiles sit in /nix/var/nix/profiles/per-user/<user>/; root’s profile uses /nix/var/nix/profiles/per-user/root/profile. With XDG base directories, a regular user’s profiles are under $XDG_STATE_HOME/nix/profiles/ instead.

For a profile named profile, the name symlink, generation link, and store path chain like this:

…/profiles/profile          → profile-7-link
…/profiles/profile-7-link   → /nix/store/…-profile

Each profile-N-link symlink is itself a GC root. The store path it targets is a symlink farm: bin/, share/, and other trees contain symlinks into installed packages—not copies of store content.

The installer typically creates ~/.nix-profile pointing at the active user profile (or $XDG_STATE_HOME/nix/profile when XDG mode is on). Activation scripts and shell profiles add its bin/ to PATH; other outputs (man pages, .desktop files) are exposed the same way.

Generations

Every mutation creates generation N + 1: a new store path and a new profile-(N+1)-link. The profile name symlink is rewired to the new link; generation N’s store path remains until nothing references it. Rolling back means switching the name symlink to an older profile-M-link—see Generation and Immutability and rollback.

Each generation’s store path includes a manifest of installed packages:

CLI Manifest file Notes
nix-env manifest.nix Nix expression listing package names and store paths
nix profile manifest.json JSON metadata for profile entries (experimental nix-command)

Both tools read and write through the same on-disk profile machinery; only the manifest format and CLI differ.

Profile types

Profiles are a shared mechanism; which profile you touch depends on the command:

Profile Typical path Managed by Purpose
User ~/.nix-profile…/profiles/profile nix-env, nix profile Per-user packages and tools
Channels …/profiles/channels (linked from ~/.nix-defexpr/channels) nix-channel Downloaded channel trees for <nixpkgs>
System (NixOS) /nix/var/nix/profiles/system nixos-rebuild Whole-system closure: kernel, services, /etc

User, channels, and system profiles evolve independently. Updating a channel generation does not change the user package profile; on NixOS, rolling back the system profile does not roll back a user’s tools.

GC roots

Each profile-N-link symlink registered with the store is a GC root. So are the user profile link (~/.nix-profile) and, on NixOS, the system profile. Garbage collection deletes only store paths with no remaining roots—historical generations stay reachable until you remove them (nix-env --delete-generations, nix profile wipe-history, nix-collect-garbage, etc.). See Garbage collection.

Classic vs modern CLI

nix-env and nix profile both mutate the default user profile through the generation machinery above. nix-env -i / -u / -e and nix profile install / remove each produce a new generation and rewrite the profile symlink.

Prefer nix profile for flake-friendly installs and JSON-oriented tooling; nix-env remains common on older workflows and in docs that assume channels. Neither edits store paths in place—both only advance or rewind the profile pointer.

Examples

# Inspect the default user profile layout (XDG or classic path)
ls -l ~/.nix-profile
ls -l "${XDG_STATE_HOME:-$HOME/.local/state}/nix/profiles/profile"* 2>/dev/null \
  || ls -l /nix/var/nix/profiles/per-user/"$USER"/profile*

# Classic: list generations and roll back
nix-env --list-generations
nix-env --rollback

# Modern (requires nix-command): history and rollback
nix profile history
nix profile rollback

# See what a generation keeps alive (store path from profile-N-link)
nix-store --query --requisites "$(readlink -f ~/.nix-profile)"

On NixOS, nixos-rebuild list-generations shows system profile generations; the boot loader can boot any listed generation—see Generations and boot.

References

See also