25 July 2026
Bringing Nix to a justfile without disturbing other developers
The dev community has accepted pinning project dependencies as an industry standard. The next logical step is pinning the dev environment itself: the exact compiler, the exact linter, the same versions in CI and on every developer’s machine. That step is still in its infancy and there is no de facto standard. CI acts as the great equalizer, but locally the usual answer is running the dev environment in Docker, and that’s cumbersome.
Nix solves pinning dev envs well, and I’m slowly rolling it out at my workplace. The catch is its high entrance fee — asking everyone to figure out local Nix setup is the fastest way to kill the effort. So Nix has to be opt-in. But baked into the default behavior, so a developer never has to remember to use it.
My teams already use justfiles.
This post is about making just serve both camps: those who opted into Nix and those who haven’t.
It doesn’t cover defining your flake or a dev shell.
The wrapper
Paste these two lines at the top of a justfile:
have_nix := `command -v nix >/dev/null 2>&1 && echo true || echo false`
wrap := if env("IN_NIX_SHELL", "") != "" { "" } else if have_nix == "true" { "nix develop --command " } else { "" }
Then prefix recipes with {{wrap}}:
test:
{{wrap}}cargo test
That’s it.
just test now does the right thing for everyone.
How it works
wrap resolves to one of two values, covering three situations:
- Already inside the dev shell —
IN_NIX_SHELLis set, sowrapis empty and the command runs as is. No point in nesting shells. - Nix is installed —
wrapbecomesnix develop --command, and the recipe runs with the flake-pinned toolchain. - No Nix —
wrapis empty again. The recipe runs against whatever is onPATH, exactly as if those two lines didn’t exist.
A colleague without Nix never sees a difference. There is nothing to install, no error message, no README section to read. They only find out the wrapper exists if they go looking.
Opting out
Sometimes a Nix user wants the system toolchain — say, to check whether a bug reproduces outside the pinned environment.
just lets you override the wrapper variable from the command line:
just --set wrap "" test
No changes to the justfile, no environment variables to remember.
For more examples you can check justfiles of git-plumber and do-next.