Nix Flakes for Small R Projects
Typical Project Structure
my-project/
├── flake.nix
├── flake.lock
├── .envrc
├── R/
└── other/
What the files do
flake.nix
Defines the environment you want:
- Which Nix package repository to use (
nixpkgs) - Which R packages to install
- Any system dependencies
Example:
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake.lock
This is the important, automatically generated, file that pins the environment to a specific commit. Even if nixos-unstable moves on, my project will continue using the exact versions recorded in flake.lock until you choose to update.
.envrc
This is used by direnv to automatically activate/deactivate the environment when I enter that folder. Instead of entering a folder and typing
use flake
with direnv installed, entering the directory automatically loads the Nix environment.
First Time Setup
Create:
flake.nix
and
.envrc
containing:
use flake
Then run:
direnv allow
We normally only need to do this once per project (or after changing .envrc) and should even be getting prompted.
Entering the Environment
If using direnv:
cd my-project
The environment loads automatically.
If not using direnv:
nix develop
This starts a shell containing the packages defined in your flake.
Leaving the Environment
If we started manually:
exit
or:
Ctrl-D
If we used direnv:
cd ..
The environment unloads automatically when you leave the directory.
Updating Packages
Current workflow:
flake.nix
flake.lock (pins exact versions)
To update to newer software:
nix flake update
This refreshes flake.lock to newer commits from the configured branch.
After updating:
git add flake.lock
git commit -m "Update Nix packages"
Stable vs Unstable
Some thoughts about which target URL to use:
Research papers / teaching materials
Use a stable branch:
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
Advantages:
- More stable
- Better long-term reproducibility
- Less risk of breakage
Personal projects
Use:
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
Advantages:
- Newer R versions
- Newer package versions
- Easier access to recent software
Remember that after flake.lock is created, both remain fully reproducible until we run:
nix flake update
Mental Model
Think of:
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
as:
“When I choose to update, get updates from this branch.”
and think of:
flake.lock
as:
“Use these exact package versions until I explicitly update them.”
That’s the key idea behind flakes.
Use the share button below if you liked it.
It makes me smile, when I see it.