We used to onboard engineers with a README full of brew, apt-get, and curl commands. It was brittle, and a touch frustrating. On his first day, a new dev to our company, Lucio, built a Nix flake to replace that manual set up process.
By the end of that week, a bunch of our developers had adopted it. Setup time dropped from thirty minutes to five, and the onboarding pain dropped just as much.
Readme
Loading...
After: Nix flake
Lucio introduced a single flake.nix file to replace this README and its manual process. The core of the solution is the devShells.default output, which declaratively defines the complete toolchain.
Loading...
This file defines all dependencies, from language runtimes d…
We used to onboard engineers with a README full of brew, apt-get, and curl commands. It was brittle, and a touch frustrating. On his first day, a new dev to our company, Lucio, built a Nix flake to replace that manual set up process.
By the end of that week, a bunch of our developers had adopted it. Setup time dropped from thirty minutes to five, and the onboarding pain dropped just as much.
Readme
Loading...
After: Nix flake
Lucio introduced a single flake.nix file to replace this README and its manual process. The core of the solution is the devShells.default output, which declaratively defines the complete toolchain.
Loading...
This file defines all dependencies, from language runtimes down to C libraries like rdkafka and openssl, in one place.
Adoption
The flake.nix PR on a Monday. On Tuesday, another dev from our team, Dave, onboarded. The entire process was git clone and nix develop. He had a fully functional, correct environment in under five minutes (mostly download time) versus the previous 30+ minute manual setup.
This rapid adoption wasn’t just about the initial setup; it was a direct result of the technical guarantees.
1. A Standard Interface: The command is nix develop. No more setup guides or per-project instructions. If you use nix-direnv, it’ll even drop you into the dev shell automatically when you enter the project folder.
2. Atomic Pinning via flake.lock: The flake.lock file is the critical component. It’s not just a package-lock.json or a Cargo.lock. It cryptographically pins the exact revisions of nixpkgs, rust-overlay, and all other inputs.
Loading...
This means a developer six months from now will get the exact same rustc, node, and openssl versions, eliminating environment drift.
Crucially, this also means adjustments to the environment are reproducible. If we need to add pkg-config, we add it to buildInputs, and the updated flake.lock guarantees every other developer gets that exact change when they next run nix develop.
3. Composability: We didn’t have to solve Rust tooling in Nix. We just imported a community-maintained solution. The inputs block acts as a package manager for our entire toolchain.
Loading...
Conclusion
Nix Flakes gave us a reproducible, composable dev environment and cut onboarding time dramatically. They’re not without cost. The syntax takes getting used to, and flakes are still evolving. But, the stability we gained in day-to-day work easily outweighed those bumps: the friction of onboarding and, just as importantly, maintaining complex dev environments was significantly reduced.
Try the same Nix flake we use to build MooseStack in the MooseStack repository.