After years of fighting with version conflicts, environments that diverge between colleagues, and endless "it works on my machine" scenarios, I discovered Nix. And for me, it's a revolution in development environment management.
Unlike traditional package managers I've tried them all (Homebrew, apt, conda, nvm...), Nix takes a purely functional approach that finally guarantees build and environment reproducibility, from laptop to CI to production.
Nix is simultaneously:
Its key feature: each package (and environment) is built in a unique path in the Nix store, derived from all its build dependencies. Two builds with the same inputs produce the same outputs, at the same path — that's the foundation of reproducibility.
DevShells are per-project development environments, described in Nix, that you activate on demand. For me, they solved four daily struggles I'd been living with for years.
/usr/local, and doesn't break other projects.flake.lock file precisely freezes the inputs used. The entire team works on the same versions.nix develop → ready to go. No more lengthy "Installation" sections in the README.Before Nix:
With Nix:
task test, task fmt, task check)Thanks to flakes and direnv/nix-direnv, each project precisely defines its tools and libraries. When entering the folder, the appropriate environment is automatically loaded, without polluting the global system.
What I've been able to do concretely, in parallel on my machine:
No more global system version headaches!
flake.nix:
{
description = "Minimal Nix devShell";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
outputs = { self, nixpkgs }: let
system = "x86_64-darwin"; # or x86_64-linux / aarch64-darwin
pkgs = import nixpkgs { inherit system; };
in {
devShells.${system}.default = pkgs.mkShell {
buildInputs = [ pkgs.nodejs_20 pkgs.python311 pkgs.git ];
# Optional environment variables and hooks
shellHook = ''
echo "[devshell] Node: $(node -v), Python: $(python3 --version)";
export PIP_DISABLE_PIP_VERSION_CHECK=1
export UV_NO_CACHE=1
'';
};
};
}
.envrc:
# Option A: basic direnv
use nix
# Option B (recommended): nix-direnv for instant activations
# use flake
Then:
direnv allow # execute once
Subsequent activations are instant with nix-direnv (shell caching).
Nix allows simultaneous installation of multiple versions of the same package, without hacks. This "time travel" is ideal for maintaining legacy projects while developing with the latest versions.
With declarative definitions and the lock file (flake.lock), I have the guarantee that the environment will be identical wherever I use it:
Locally: My MacBook, a colleague's, my Linux VM - same versions, same behavior.
In CI: GitHub Actions, GitLab CI, doesn't matter - CI uses exactly the same tools as I do locally.
In ephemeral environments: The most impressive is with tools like Devin.ai. I can share my flake.nix and the AI instantly has the same environment as me, without manual installation, without complex setup.
Result: no more "it works locally but not in CI", no more time wasted synchronizing versions between developers and automated systems.
Near-instant onboarding:
nix developThis is actually the approach we adopted as a team: I started by proposing a simple flake.nix on a pilot project, without forcing anyone. Result: progressive and natural adoption, without friction.
Nix effectively replaces a myriad of tools:
One command to install everything on a new machine, one logic for all stacks.
Development servers: No more begging the system admin to install the right version of Node or Python. I deploy my flake.nix, and the environment is identical to my laptop.
With AIs like Devin: This is where it gets magical. I share my Nix environment, and the AI instantly has the same setup as me. No "how to install X", no environment differences.
In CI/CD: No more version problems between my machine and CI. Same Nix, same environment, same results.
Useful complements:
devenv.sh (Cachix): ergonomic overlay for local services (DB, queues) and team scriptsprocess-compose: orchestration of multiple dev processes in the shellDespite this, my return on investment has been clear in productivity and peace of mind.
system (e.g., via flake-utils).The Nix ecosystem exceeds 120,000 packages. More and more teams I meet are adopting it, whether in production or just to standardize their dev environments.
For me, Nix has been a game changer. No more "it works on my machine", no more hours lost debugging version conflicts, no more painful onboarding.
Today, I can't imagine starting a project without a Nix devShell. It's become as natural as creating a README.
Yes, I spent a few weekends understanding the concepts — but the daily peace of mind is invaluable. And when a colleague tells me "your project doesn't work on my machine", I know it's just because they haven't done nix develop yet 😉