Nix, the shell bootstrapper
Hayden Young
Posted on July 19, 2020
So recently I swapped out Arch Linux for NixOS, mainly because I could bootstrap my entire PC with a configuration file. I never really looked into nix as a tool until today. Of course, I've been using nix as a package manager for about a month due to NixOS, but I'd never looked into nix itself for development purposes. And oh boy, was I glad that I did. And here's why.
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "node";
buildInputs = [
nodejs
];
shellHook = ''
export PATH="$PWD/node_modules/.bin/:$PATH"
alias run='npm run'
'';
}
So what the fork is this?! Well, calm down a little and I'll tell you.
This beautiful piece of functional code you see before you is a Nix Derivation. It's used in this instance to make a complete dev environment for me for nodejs. It lives in a file called default.nix
, and allows for anyone to just come along and run nix-shell
and have a full Node.js development environment complete with an alias of npm run
to run
.
The fact that I can do this without having to go download NVM or nodenv or similar is... Well, let's just be calm and say it saves me a lot of headaches.
So let's break that file down.
with import <nixpkgs> {};
This tells Nix to import the nixpkgs
package registry, which is the official source for nix packages. This becomes important later.
stdenv.mkDerivation {
# ...
}
Does what it says on the tin really. Makes a new nix derivation, defined & configured by the contents of the block. This is what Nix evaluates to produce our dev environment.
name = "node";
This just gives our derivation a name, duh. I've called it node
here, but you could call it stopwritingpostsondevyoudontknowanything
for all I care.
buildInputs = [
nodejs
];
This is where that nixpkgs
import line comes in handy. This is telling Nix to install the latest LTS version (at least the current LTS version recorded in the nixpkgs repo) of Node.js, and make it available to us in the dev environment. You could add anything here. Need to build native extensions? Throw gcc
and automake
in here!
shellHook = ''
export PATH="$PWD/node_modules/.bin/:$PATH"
alias run='npm run'
'';
So this is essentially a bash script that will be called when the environment is created. In this instance, it's adding the node_modules/.bin
directory to our PATH
variable, so we can call any NPM-installed binaries as if they were globally installed on our system. Really cool for those obscure linting commands you only ever need to run once or twice.
It also aliases npm run
to run
, allowing me to do run build
instead of npm run build
. Tiny amount of time saved, but I love tiny, insignificant time saving measures.
So that's the default.nix
file covered.
But Hayden, you keep telling me how cool and epic and amazing and <insert other synonym for 'cool' here>, but you haven't shown me anything yet.
no talk me, i angy.
Well, don't be so angy. You want a demo putting it all together? Have one.
See? It's fantastic.
Well, that about wraps this up.
TL;DR, Nix is brilliant and you should try it out now. Go. Leave the room please. Go. I don't want you around anymore. Go try Nix. Now. BYE!
Posted on July 19, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.