← Back to Course Index

Lesson 5: Writing flake.nix

Create reproducible development environments

Learning Objectives

What is a Flake?

A flake is a modern, reproducible Nix package. It's a project structure that includes:

Why flakes matter: They solve the "works on my machine" problem by pinning exact versions and making dev environments self-contained and shareable.

Anatomy of a Flake

Here's a minimal flake.nix:

{ description = "My dev environment"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; in { devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ nodejs python3 git ]; }; } ); }

Breaking It Down

1. Inputs: Your flake's dependencies

inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; };

2. Outputs: What your flake produces

outputs = { self, nixpkgs, flake-utils }: { devShells.default = ... packages.default = ... apps.default = ... };

3. mkShell: Development environment

pkgs.mkShell { name = "my-dev-env"; buildInputs = with pkgs; [ nodejs python3 gcc ]; shellHook = '' echo "Dev environment loaded!" ''; }

Using Your Flake

Enter the dev environment:

nix flake enter # Or: nix develop

Update dependencies:

nix flake update

Try It Yourself

Create Your First Flake

Create a new directory:
mkdir my-nix-project cd my-nix-project
Create flake.nix:
{ description = "My first Nix dev environment"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; in { devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ nodejs python3 ]; }; } ); }
Initialize the flake:
nix flake update

This creates flake.lock

Enter the environment:
nix develop

You're now in a shell with node and python available!

Verify your tools are available:
node --version python3 --version exit

Key Concepts

flake.lock is crucial: It pins exact versions/commits. With flake.lock in version control, anyone can reproduce the exact same environment.

Key Takeaways