Nix Quickstart
Nix seems to stump a lot of newcomers. I had a few failed starts at trying at Nix myself, but I now find myself at a happy amount of knowledge where Nix is more helpful than hurtful.
How I think of Nix
Most likely, you’ve worked with one of the following before:
Cargo.toml
package.json
Gemfile
requirements.txt
Example package.json
{
"name": "example",
"version": "1.0.0",
"devDependencies": {
"ts-node": "^10.5.0",
},
"dependencies": {
"react": "18.2.0"
}
}
All of these attempt to define a project’s dependencies for that particular language. We like these files because it means that a new computer can quickly and correctly install all the required language-specific dependencies, assuming they have the language (compiler, interpreter..) and/or package manager installed. Here, we are attempting to create a deterministic environment.
So let’s take it up a level. Wouldn’t it be nice if we could not only define the language-specific dependencies, but just also the language / binaries in general? That’s where Nix comes in. Here’s an example shell.nix
file:
with import <nixpkgs> { };
pkgs.mkShell {
buildInputs = [
nodejs
yarn
];
shellHook = ''
alias i='yarn'
alias s='yarn start'
'';
}
Running nix-shell
will start a new shell with nodejs
and yarn
installed (try which nodejs
or which yarn
). It will also load the aliases i
and s
that you can use in this new shell.
How I use nix
Very basics, install Nix.
I like to add this global alias for convenience
alias ns='nix-shell'
For each project, I define a shell.nix
file in the root directory with the dependencies I need. You can easily find available packages on Nix search which I keep bookmarked.
Finally, I call ns
when I am in a project. I use ctrl+D
or exit
to leave the Nix shell and return to my default shell.
Why I like this setup
The biggest is that it makes multi-computer dev a lot less painful. The only software I need to install on any computer I own is Nix
. It also helps that most of the time, Nix works the same way on Linux as it does on MacOS.
The more obvious one is that I have relatively deterministic setups for all my projects. Storing aliases in my shell.nix also means I can record the common commands that need to be run on any project.