You have installed Nix. Now let’s play with the nix command.
In this tutorial we will learn how to use existing packages from the nixpkgs repository and elsewhere. We will not be writing any Nix language code yet (we reserve that for the next tutorial).
Running a package
As of this writing, nixpkgs has over 80,000 packages. You can search them here. Search for “cowsay” and you will find that it is available in Nixpkgs.
We can download and run the cowsay package as follows:
$ nix run nixpkgs#cowsay "G'day $USER"
____________
< G'day srid >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$nix run
nix run command will run the specified package from the flake. Here nixpkgs is the flake, followed by the letter #, which is followed by the package (Derivation) name cowsay that is outputted by that flake. See Flake URL for details on the syntax.
Transient shells
One of the superpowers of Nix is that it enables us to create isolated shell environments containing just the packages we need.
For example, here’s how we create a temporary shell containing the “cowsay” and “fortune” packages:
$ nix shell nixpkgs#cowsay nixpkgs#fortune
❯
From here, you can verify that both the programs are indeed in $PATH. But where do they live?
❯ which cowsay
/nix/store/n1lnrvgl43k6zln1s5wxcp2zh9bm0z63-cowsay-3.7.0/bin/cowsay
❯ which fortune
/nix/store/mfw77f008xy0zb7dqdyggw0xj2gd4jjv-fortune-mod-3.20.0/bin/fortune
❯ fortune | cowsay
________________________________
/ The longer the title, the less \
\ important the job. /
--------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
When you exit this shell (type exit or press Ctrl+D), cowsay and fortune will no longer be available in your path.
Instead of entering an interactive shell, you can also run commands one-off using the -c option.
nix shell nixpkgs#cowsay nixpkgs#fortune -c sh -c 'fortune | cowsay'Under the hood
You might have noticed the specific paths in the which output above, looking like /nix/store/...-cowsay-....
Technically, a Nix package is a special directory (a Store path) inside the Nix Store (/nix/store), built using instructions from a Derivation.
To inspect the contents of a package without running it or creating a shell, we can use nix build. This will realize the package in the store and print its path:
$ nix build nixpkgs#cowsay --no-link --print-out-paths
/nix/store/n1lnrvgl43k6zln1s5wxcp2zh9bm0z63-cowsay-3.7.0
We can then inspect this directory structure (using tree, which we can also run via Nix!):
$ nix run nixpkgs#tree /nix/store/n1lnrvgl43k6zln1s5wxcp2zh9bm0z63-cowsay-3.7.0
/nix/store/n1lnrvgl43k6zln1s5wxcp2zh9bm0z63-cowsay-3.7.0
├── bin
│ ├── cowsay
│ └── cowthink -> cowsay
└── share
└── cowsay
├── cows
│ ├── DragonAndCow.pm
│ ├── Example.pm
│ ├── Frogs.pm
│ ├── ...
/nix/store is a special directory representing the Nix Store. It is read-only and all components within it are immutable. Nix fundamentally is about manipulating these store paths in a pure and reproducible fashion.
Installing a package
This section explains how to install a package imperatively. For a better way of installing packages (declaratively), see home-manager.
If you want to keep a package available permanently (not just in a transient shell), you can install it into your user profile using nix profile install:
$ nix profile install nixpkgs#cowsay nixpkgs#fortune
$ which cowsay
/home/user/.nix-profile/bin/cowsay
nix profile install creates symlinks under $HOME/.nix-profile, pointing to the actual files in the Nix Store.
Where do packages come from?
So far we have been getting software from nixpkgs. What is that?
It is the specific identifier for the nixpkgs repository (https://github.com/nixos/nixpkgs) defined in your local Flake registry:
$ nix registry list | grep nixpkgs
global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable
A registry is simply a shortcut mapping (like nixpkgs) to a full Flake URL (like github:NixOS/nixpkgs/nixpkgs-unstable).
We can confirm which version of nixpkgs we are using:
❯ nix flake metadata nixpkgs --json | nix run nixpkgs#jq -- -r .locked.rev
317484b1ead87b9c1b8ac5261a8d2dd748a0492d
By default, nixpkgs corresponds to a rolling branch (nixpkgs-unstable), which updates automatically. To pin it to a specific version, or to manage it declaratively, see home-manager.
You are not required to use a registry. Without a registry, getting a package off nixpkgs would instead involve its fully qualified URL:
$ nix run github:NixOS/nixpkgs/nixpkgs-unstable#cowsay
...Software from elsewhere
nixpkgs is the main repository, but Nix allows installing software from anywhere. You can run or install programs from any flake by specifying its URL.
For example, Emanote (which builds this website) can be run directly from its own GitHub repository:
$ nix run github:srid/emanoteOr installed:
$ nix profile install github:srid/emanoteWhat’s next
- Next Tutorial: We will start writing our own simple Nix expressions and flakes.
- Home Manager: If you want to manage your shell environment and packages declaratively (recommended for personal machines).
- NixOS: If you are ready to configure your entire operating system with Nix.