How does nix shell work, internally?

Where can I learn about how nix develop / nix shell work? For instance, how does the nix CLI know what environment variables to set, which hooks to run and which packages to provide?

I know that the mkshell package has a bash script inside its output when built, but that file specifically says that it shouldn’t be relied on.

Aside from that warning, the mkShell definition just says it’s “special”: nixpkgs/pkgs/build-support/mkshell/default.nix at 7eac31cc902e76c3caa7558eb2a798bde8706156 · NixOS/nixpkgs · GitHub

I want to know what makes it special. Documentation links would be really really great.

2 Likes

nix-shell and its 2.0 successors put you “in” the (bash) environment that the derivation’s builder would receive, and it executes a specfic additional command. mkShell just creates a derivation whose entire purpose it is to feed the correct things into the build environment to create the shell you design with it, instead of a real derivation. That’s why it’s “special” - it’s kind of a hack that abuses nix’ native feature to create “build” shells to make something that isn’t a build shell at all.

The docs for it are here: nix-shell - Nix 2.34.7 Reference Manual

The nix develop and nix shell docs also explain this, but much less well.

2 Likes

Come to Nixcon and find out! (assuming my talk is accepted :))

In brief though, have a look at nix/src/nix/get-env.sh at d967870cc6036660629db67852e225bbbef34aef · NixOS/nix · GitHub. nix develop replaces a derivation’s arguments to bash with that script, which outputs a JSON object of the stdenv environment with all its vars and functions, and then writes an RC script from it and runs that to enter the dev shell.

4 Likes

That’s really cool! So this is the script which extracts the environment, and there’s another script somewhere which it uses to setup the shell? I’m interested in emulating the steps that nix shell does, but doing it without the nix cli.

Sadly I won’t be at nixcon but the talk sounds really fun!

Also have a look at https://github.com/NixOS/nixpkgs/pull/509697, which re-implements all of the nix develop logic directly in stdenv. Once this gets in, there will be no need for nix develop to do anything really.

4 Likes