nix-shell provides ad-hoc shell environments, in which you can immediately use any program packaged with Nix, without installing it permanently on the system. Link to Nix shell manual.

Enter the program name you want to run in search.nixos.org to find packages that provide it.

Ad-Hoc (Imperative) Shell Environment

To create a Nix shell environment, with a list of packages installed, we can use the following command. If you want to create shell environment declaratively, read this section instead.

nix-shell -p <package_1> <package_2>

The first invocation of nix-shell for these packages may take a while to download all dependencies.

For example, if cowsay and lolcat are not already installed on your system and you try to run them, we will get the following errors:

cowsay no can do
 
# Output: Command 'cowsay' not found
echo no chance | lolcat
 
# Output: Command 'lolcat' not found

Now, we will create a Nix shell environment, install these packages and run them again.

nix-shell -p cowsay lolcat

It will open the shell environment:

[nix-shell:~]$ 

Let’s try to run those packages commands again within the shell:

[nix-shell:~]$ cowsay no can do
 ___________
< no can do >
 -----------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
[nix-shell:~]$ echo no chance | lolcat
no chance

Exiting Shell

Type exit or press CTRL-D to exit the shell, and the programs won’t be available anymore.

[nix-shell:~]$ exit
exit

Checking Package Versions

We can also check the package versions and package paths installed by the Nix shell:

nix-shell -p cowsay lolcat
 
[nix-shell:~]$ which cowsay
/nix/store/j4gg....-cowsay-3.8.4/bin/cowsay
 
[nix-shell:~]$ which lolcat
/nix/store/g8fai....-lolcat-100.0.1/bin/lolcat

Notice how the packages are saved in /nix/store.

Declarative Shell Environment (shell.nix)

In the Ad-Hoc (Imperative) Shell Environment section, we saw how to imperatively create shell environments using nix-shell -p command. This is great if you want to quickly test packages without installing them permanently. But there are few drawbacks like:

  • Less (ergonomically speaking) reproducibility
  • Less possible customizations for the shell environment
  • Always being required to type -p <package_1> <package_2> when we enter the shell again

In this section, we will see how to create reproducible shell environments with a declarative configuration file shell.nix. This file then can be shared with anyone to recreate the same environment on a different machine.

Basic shell.nix File

  1. Let’s first create a test directory:
mkdir test-dir
cd test-dir
  1. Create a basic shell.nix file with the following content. There is detailed explanation about this content here.
let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in
 
pkgs.mkShellNoCC {
  packages = with pkgs; [
	cowsay
	lolcat
  ];
}
  1. Enter the environment by running nix-shell in the same directory as shell.nix. The first invocation of nix-shell for these packages may take a while to download all dependencies.
nix-shell
  1. Now, let’s try to run cowsay and lolcat commands within the shell environment:
[nix-shell:~/test-dir]$ cowsay hello | lolcat
 _______ 
< hello >
 ------- 
		\   ^__^
		 \  (oo)\_______
			(__)\       )\/\
				||----w |
				||     ||
  • nix-shell by default looks for a file called shell.nix in the current directory and builds a shell environment from the Nix expression in this file.
  • Packages defined in the packages attribute will be available in $PATH.

Environment Variables

You may want to automatically export certain environment variables when you enter a shell environment.

  1. Set GREETING so it can be used in the shell environment:
let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in
 
pkgs.mkShellNoCC {
  packages = with pkgs; [
	cowsay
	lolcat
  ];
  
  GREETING = "Hello, Nix";
  
}
  1. Enter the shell again, and run echo $GREETING:
[nix-shell:~/test-dir]$ echo $GREETING
Hello, Nix

Startup Commands

Read this section on how to run some shell commands before entering the interactive shell environments.

Set up Python Development Environment

You can read this example to see how to set up a development environment for any Python project.

Automatic Environment Activation

Read direnv.

Garbage Collection

If you’re done trying out Nix for now, you may want to free up some disk space occupied by the different versions of programs you downloaded by running the examples:

nix-collect-garbage

Reproducible Interpreted Scripts

Read this guide on how to create reproducible interpreted scripts using Nix shell.