Configure a nix flake development shell
14 March 2025 | Updated on 25 March 2025
Nix is a tool that allows you to make reproducible, declarative and reliable development environments.
You can define nix development environments via nix flakes.
Nix flakes allow really advanced workflows. This article only describe how to create a basic flake with a dev shell.
Prerequisites
- install nix on your system
- You can follow this guide for macOS
- enable the flakes feature as described in the article about flakes
Create a flake
- flakes are defined in
flake.nix
files - these are usually placed in the root of your git repo project
- the following flake defines
- a dev shell for linux and mac computers
- and installs two cli tools (eza, bat)
flake.nix
{
description = "nix flake dev shell";
# Nixpkgs / NixOS version to use.
inputs.nixpkgs.url = "nixpkgs/nixos-24.11";
outputs = { self, nixpkgs }:
let
# System types to support.
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
# Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'.
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
# Nixpkgs instantiated for supported system types.
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
in
{
# Add dependencies that are only needed for development
devShells = forAllSystems (system:
let
pkgs = nixpkgsFor.${system};
in
{
default = pkgs.mkShell {
buildInputs = with pkgs; [
# search packages: https://search.nixos.org/packages
# add packages here
# 2 examples:
# eza (a modern replacement for ls)
eza
# bat (cat clone with syntax highlighting)
bat
];
};
});
};
}
Check flake file
it is important that you add/stage the flake.nix file to your git repo
- otherwise the following command will not work
- but you only need to stage the file. a commit is not required yet
then you can check if the
flake.nix
is valid via:nix flake check --all-systems
If you haven’t used the defined dependencies before, Nix will download everything automatically.
Nix will also generate a
flake.lock
file. You will never edit this file manually.
Commit flake to git
- if you are happy with your flake configuration you should commit both files to git (
flake.nix
andflake.lock
)
How to change flake later
- you can change the
flake.nix
file in the future (e. g. add/remove packages) - after editing the file you should run the following command to update the lock file
nix flake update
- commit both files again
Use dev shell
Open nix development shell
- use a basic dev shell
nix develop
- use a zsh dev shell
nix develop --command zsh
Run commands
- you can use the shell like usual
- your defined packages will be available
which eza
- the binary path will be some symlink to nix store
Exit dev shell
- exit a nix development shell like usual via
exit
orctrl + d
Use flake with vscode
- there are vscode extensions to activate nix flakes from inside vscode
- but in my opinion the best approach is to start vscode an already activated nix flake development shell
- this way all vscode processes will use the nix environment
Start vscode in nix shell
via two commands
nix develop
# ... then in nix shell:
code .
via one command
nix develop --command code .
Ensure correct environment paths
macos
- fixing environment variable path problem in zsh macos
- especially when opening
code .
innix develop
shell
- especially when opening
- without the following settings vscode will change the user path variable and the nix development path would be incorrect
- then tools/binaries from the nix flake do not get the highest priority
- so you should add these settings in your vscode user (or workspace) settings to ensure correct behaviour
settings.json
{
"terminal.integrated.defaultProfile.osx": "zsh",
// this does NOT work:
// "terminal.integrated.inheritEnv": false,
// but this does work:
"terminal.integrated.profiles.osx": {
"zsh": {
"path": "zsh",
"args": [], // just set this empty
// do not use this!
// "env": {
// "PATH": "${env:PATH}"
// }
}
}
}