Getting Started with Nix¶
This section introduces basic Nix usage.
- Install packages into the system through user profiles.
- Manipulate and select channels.
- Search for packages.
Nix vs traditional package managers¶
- Getting the package content — either by downloading it from a cache or by rebuilding it.
- Making the package available to the user.
These two parts are very close with the aforementioned package managers,
as the way to make packages available to the user is to rely on some standard (or distribution-specific) directories.
For example, executable files may be put into
/usr/bin, libraries in
/usr/lib and C include files in
The approach taken by Nix is different.
Nix stores all packages into a common place called the Nix store, usually located at
Each package is stored in a unique subdirectory in the store, and each package has its own tree structure.
For example, a SimGrid package might be stored in
The package path is composed of a cryptographic hash of all the package inputs followed by the package name (more information about this can be found in Nix pills about store paths).
The package file structure looks like the following.
. ├── bin | ├── smpicc | ├── smpirun | └── ... ├── include │ └── ... ├── lib │ ├── libsimgrid.so │ └── ... └── share └── ...
This storage system has very interesting properties, such as allowing the simultaneous presence of as many versions of a package as desired.
However, it makes the “Making the package available to the user” more complex.
Nix heavily relies on environment variables to make this possible.
For example, an environment that contains the aforementioned SimGrid package and another
hello package would put both
/nix/store/06vykrz1hmxgxir8i74fwjl6r9bb2gpg-hello-2.10/bin into a
$PATH environment variable.
As managing such environment variables manually would be tedious, Nix propose many commands that manage them for you.
Nix profiles are an abstraction that solves the “Making the package available to the user” issue discussed above.
A profile describes an environment, that is to say a set of packages that are made available to the user.
Managing profiles is mostly done with the
Curious readers may be interested in Nix’s official profile documentation for an explanation about how profiles work internally.
To install a package on your default profile, you can type:
nix-env -i package_name
For instance, to install the fortune teller application, use
nix-env -i fortune-mod.
To obtain the list of the packages installed in the current profile, you can use the command:
nix-env --query "*"
You can remove an installed package from your current profile with:
nix-env -e package_name
It is possible to remove several packages with a wildcard:
nix-env -e "*".
However, this command will also remove the package
nix itself from the current profile.
As a result, the current Nix profile will require a manual intervention to be recovered, as Nix commands will not be callable as usual.
A last profile feature worth mentioning here is the ability to go back to the previous generation (a new generation is created at each modification of the profile):
The packages available in Nix are defined in a git repository that contains the definition of all the packages (see Nixpkgs source code). A channel, can be seen as a nixpkgs branch (as in git branch) that is validated by a continuous integration system. Several channels exists, the list of the currently available channels is available here.
In this section we introduce the channel fonctionnality of the Nix package manager as it is a convenient way to interact with the package manager, and it will give you a better understanding of what is happening under the hood.
However, using channels is not fully reproducible, as a channel may evolve to incorporate updates. When package reproducibility become a major concern, as it is the case in this tutorial, it is preferable to refer to a pinned version of the nixpkgs repository instead — i.e, a specific commit of the repository or an immutable archived tarball. The ability to pin the version of nixpkgs is powerful, it will ensure that a package is always constructed from the same Nix source. As we go deeper in the tutorial we avoid using channels in favor of pinned environments.
To list the channel currently installed on your system.
nix-channel --list #<output> nixpkgs https://nixos.org/channels/nixpkgs-unstable
The command returns a name for each channel (e.g.,
nixpkgs) and an URL.
nix-env with the parameter -A, one can select the channel to get the package from.
Such a command looks like
nix-env -iA channelname.packagename.
One can see that the default channel installed with Nix points to nixpkgs-unstable. Let us install a more stable channel instead. At the time of this tutorial (2019-06), the latest stable channel is nixpkgs-19.03.
# Add the channel 19.03 with the name nixpkgs. nix-channel --add https://nixos.org/channels/nixos-19.03 nixpkgs nix-channel --update
However, this had the effect to completely override the unstable channel. The unstable channel can be added back with another name.
# Add the unstable with the name `unstable` nix-channel --add https://nixos.org/channels/nixpkgs-unstable unstable nix-channel --update # Check the result nix-channel --list
Now that both channel are installed on your system, we can try installing packages from both of them.
# Installing Simgrid from the stable channel. nix-env -iA nixpkgs.simgrid # And installing it from unstable, this will override the current simgrid. nix-env -iA unstable.simgrid
Searching a package can be done via
nix search simgrid
Upgrading a package:
nix-env --upgrade simgrid
nix-build can be used to build a package defined with the Nix Expression Language.
For instance, building the hello package from the nixpkgs channel can be done like this:
nix-build '<nixpkgs>' -A hello
The resulting package is build and added to the nix store.
For conenience, a link pointing to the package that has been put into the store is created in
nix-shell allows to enter a shell in a controlled environment, or to run commands in such an environment.
This is extremely powerful and convenient, and will be detailed in the next section of this tutorial.
For now, you can see
Many other Nix commands exist.
nix-collect-garbagecleans the Nix store of unused packages.
nix-storeinteracts with the nix store.
nix-copy-closureis convenient to synchronize parts of Nix store between several machines.
If you wonder how to do X with nix commands, the Nix commands’ cheatsheet can help you.