nix-shell.2
Enter a reproducible build environment
TLDR
Start with nix expression in shell.nix or default.nix in the current directory
Run shell command in non-interactive shell and exit
Start with expression in default.nix in the current directory
Start with packages loaded from nixpkgs
Start with packages loaded from specific nixpkgs revision
Evaluate rest of file in specific interpreter, for use in #!-scripts (see
SYNOPSIS
nix-shell [options] [expression-path] [--run command]
PARAMETERS
-A attribute or --attr attribute
Specifies an attribute within a Nix expression (e.g., a flake.nix or shell.nix) to build a shell from. This is useful for selecting specific development environments defined within a larger Nix project.
--arg name value
Passes a Nix value to the function defined in the Nix expression that describes the shell. This allows for parameterizing the environment.
--argstr name string
Similar to --arg, but specifically passes a string value to the function defined in the Nix expression.
--pure
Creates a completely isolated, 'pure' shell environment, discarding most inherited environment variables from the parent shell. This helps ensure greater reproducibility by minimizing external influences.
--run command
Executes the specified command within the constructed shell environment instead of entering an interactive shell. The shell exits immediately after the command completes.
-p packages
Adds the specified packages to the shell environment on the fly without requiring a Nix expression file. Multiple packages can be listed, separated by spaces.
--keep VAR
Preserves the specified environment variable VAR from the parent environment even when using the --pure option. This is useful for retaining essential variables like SSH_AUTH_SOCK.
-I path
Adds path to the Nix search path. This influences how Nix resolves imported files within expressions.
DESCRIPTION
nix-shell is a command in the Nix ecosystem that allows users to create and enter a shell environment where specific dependencies are available. It's particularly useful for development, testing, and building software without globally installing packages. Instead of modifying the system-wide environment, nix-shell constructs a temporary, isolated environment based on a Nix expression (typically shell.nix or a flake.nix entry). This expression defines the packages, build tools, and environmental variables required for a project.
When invoked, nix-shell builds or fetches these dependencies and then spawns a new shell (e.g., bash) with the specified PATH, NIX_BUILD_CORES, and other variables set up to make the dependencies accessible. This ensures reproducible development environments, prevents dependency conflicts, and simplifies project setup for collaborators. It supports interactive use, where you can explore the environment, or non-interactive use, where it executes a command within the constructed environment. It's a cornerstone for reproducible development and testing workflows within the Nix ecosystem, enabling users to 'jump into' a specific project's environment without polluting their global system.
CAVEATS
While powerful, nix-shell environments can sometimes be slow to initialize if dependencies need to be built or downloaded for the first time, potentially consuming significant disk space in the Nix store. Users should also be aware that nix-shell is part of the legacy Nix command set; for modern, reproducible development environments, the Nix team increasingly recommends using nix develop (part of the experimental Nix Flakes feature), which offers improved reproducibility and structure for complex projects. Although nix-shell remains widely used and functional, its role in new projects might be superseded by nix develop.
NIX EXPRESSIONS AND <I>SHELL.NIX</I>
The behavior of nix-shell is primarily determined by a Nix expression, often found in a file named shell.nix in the current directory or specified as an argument. This expression defines the packages, build tools, and environment variables that constitute the shell environment. For projects using Nix Flakes, nix-shell can also use the devShell attribute within a flake.nix file to define the environment.
INTERACTIVE VS. NON-INTERACTIVE MODES
nix-shell can be used in two primary modes. By default, it spawns an interactive shell (e.g., bash) where the user can execute commands within the defined environment. Alternatively, using the --run command option, nix-shell can execute a specific command in the constructed environment and then exit, making it suitable for scripting or continuous integration pipelines.
HISTORY
Nix was created by Eelco Dolstra as part of his PhD research on reproducible software deployment. nix-shell has been a fundamental component since early versions of Nix, providing a simple way to enter isolated development environments. It predates the introduction of Nix Flakes and the unified nix command-line interface, which led to the development of nix develop as a more structured and reproducible successor for defining project environments. Despite newer alternatives, nix-shell remains widely used for quick, ad-hoc environment setup and for interacting with legacy Nix expressions. Its design exemplifies Nix's core principle of reproducible environments.


