TLDR :)
I like the Nix package manager, because I don’t have to have every tool and compiler installed on my machine polluting my userspace. If you’ve ever heard of Nix, I bet you’ve also heard a sentence like that. There are multiple ways to set up your development environment on Nix (not just NixOS, the Nix package manager is cross platform!), but I currently like nix-shell
the best.
Nix shell command
The simplest way to start a new environment is to just run the command
nix-shell -p cargo
if you want the cargo package in the shell. You can also specify multiple packages after the -p
flag, for example
nix-shell -p cargo trunk
But if you have a project in your folder with multiple dependencies, it can quickly get tedious to remember all the package names and also to type it out. The nix-shell
command also has other features and typing out the command is just not practical. This is why the shell.nix
file is so great.
shell.nix
The shell.nix
file is basically a nix function that executes a mkShell
function using your system’s nixpkgs
collection and returns the result (a shell). This makes nix-shell
much faster and more lightweight than flakes if the specific package versions in the wanted environment are not that important. The most basic shell.nix
file looks like this:
{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell {
packages = with pkgs; [
# packages you need
];
}
To use it, you just need to run the command nix-shell
without any arguments in the same directory, which will then set up an environment using these packages. This will probably take a minute the first time you run it (depending on how many packages you need), but luckily they will stay in your nix store, so the following times it will be almost instant.
Basically the shell.nix
file is a function that takes an argument of an attribute set with one inner value called pkgs
. The question mark sets the default value for pkgs
to the system’s current nixpkgs
. Then the pkgs.mkShell
function builds the wanted shell with the needed packages.
Other inputs
The pkgs.mkShell
function can take some other inputs. You may read about it in the official documentation, but one you need to know is shellHook
. It allows you to run shell commands once entering the nix-shell
. You can use it to set environment variables, change your prompt or just echo something out.
My Rust environment
{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell {
packages = with pkgs; [
cargo
rustc
rust-analyzer
];
shellHook = ''
PS1='\[\e[38;5;160m\]\[\e[92m\] at \[\e[94m\]\w\[\e[0m\] \$ '
echo "Entered rust devenv..."
''; # run bash code on shell startup
}
nix-shell