nix
Nix is a declarative-based distro where in contrary to the standard imperative approach, the whole OS is configured by a file instead of invoking commands first.
There are two ways to use nix:
- nixOS
- nix package manager
I prefer to use the nix package manager for now since I do not have the time to invest in learning the OS. Besides, you can install the nix-package manager on any linux distro to try it out.
Nix Package Manager
As a software developer, you are inevitably going to be faced with the problem of managing development environments. X project uses X set of packages, Y project uses Y set of packages, and Z project uses X and Y set of packages.
This becomes a headache and another overhead to the things you are going to think about when developing applications. Thankfully, the nix package manager is here!
One thing I really love about the nix package manager is its declarative nature.
No need to check each package.json
, requirements.txt
, or composer.json
files for each project.
You can just list them out in a shell.nix
or flake.nix
file and you’re good to go.
devenv.sh
Imagine this structure for your projects:
/projects
│── main.py
│── project-1/
│ │── shell.nix
│── project-2/
│ │── shell.nix
│── project-3/
│ │── shell.nix
│── project-4/
│ │── shell.nix
│ │── ...
│── ...
Imagine you are frequently switching between projects 1 to 4, and everytime you switch, you would have to activate the shell.nix for each project. That would be a hassle wouldn’t it? That’s where devenv.sh comes in, I used this for a while to test out the power of nix and it was really cool. Here are some pros and cons:
PROS
- Automatic shell activation
- Per project dependencies
- No base shell conflict
CONS
- Too many files involved in configuration (
devenv.nix
,devenv.lock
,.envrc
,.devenv
, etc.) - Too many dependencies (
direnv
,devenv
,nix
, etc.)
In my opinion, the cons aren’t too bad, but the second con made me stop using it since I would have to maintain direnv
and devenv
separately.
Installation
Here is how to install devenv.sh
Install nix
sh <(curl -L https://nixos.org/nix/install) --daemon
# or in arch
sudo pacman -S nix
Install devenv
nix-env --install --attr devenv -f https://github.com/NixOS/nixpkgs/tarball/nixpkgs-unstable
# or in arch
sudo pacman -S devenv
Install direnv
curl -sfL https://direnv.net/install.sh | bash
# or in arch
sudo pacman -S direnv
Put this in your bashrc, and source it
eval "$(devenv direnvrc)"
use devenv
Usage
In order to create a devenv, you run the command:
devenv init
It’s best to do this in a project root folder. The above command will create multiple files:
- devenv.nix
- devenv.yaml
- .envrc
- .gitignore
After you have initialized the devenv, you can then edit the devenv.nix
file to add packages to the env.
{ pkgs, ... }:
{
env.GREET = "hello";
packages = [ pkgs.jq ]; # Add your packages here.
# You can browse nix packages for packages you want to add.
enterShell = ''
echo $GREET
jq --version
'';
}
To start the shell, just invoke the command:
devenv shell
NOTE
If you installed direnv with the steps above, you would notice that there will be logs that would show activating the env upon changing the
devenv.nix
file.
To check the current devenv details, you can run:
devenv info
If you have direnv installed, you might notice that the shell prints out a lot of logs when activating an environement
You can suppress it by adding this to your ~/.config/direnv/direnv.toml
fil:
hide_env_diff = true
Extra info
Updating devenv
nix-env --upgrade --attr devenv -f https://github.com/NixOS/nixpkgs/tarball/nixpkgs-unstable
Updating devenv inputs
devenv update
Cleaning up devenv (garbage collection)
devenv gc