Nix for Reproducible Dev Environments

Every project has a list of dependencies: Go 1.22, Node 20, PostgreSQL 16, protoc, golangci-lint. The traditional approach is a wiki page that says “install these things.” It is always out of date.

Nix solves this by declaring dependencies in a file that deterministically provides the exact versions you need, isolated from the rest of your system.

Getting Started with devenv

devenv is a friendly wrapper around Nix for development environments. Install it:

nix-env -iA devenv -f https://github.com/NixOS/nixpkgs/tarball/nixpkgs-unstable

Create a devenv.nix in your project:

{ pkgs, ... }:

{
  languages.go.enable = true;
  languages.go.package = pkgs.go_1_22;

  packages = [
    pkgs.golangci-lint
    pkgs.buf
    pkgs.postgresql_16
  ];

  services.postgres = {
    enable = true;
    initialDatabases = [{ name = "myapp"; }];
  };
}

Enter the environment:

devenv shell

You now have the exact Go version, tools, and a running PostgreSQL instance. No global installs. No version conflicts.

direnv Integration

Add a .envrc file:

use devenv

Now every time you cd into the project, your shell automatically loads the right tools. Leave the directory, and they disappear.

Why This Matters

  • New team members run devenv shell and they are ready. No setup docs.
  • CI uses the same Nix definitions, so local and CI environments are identical.
  • Upgrading a tool is a one-line change in devenv.nix, reviewed in a PR like any other code change.