I think it’d be helpful to know the story here:
nix-shell
was originally designed to debug derivation build processes. You hand it a derivation, and instead of building it, it drops you into a shell very similar to the derivation’s build env, so you can walk through the stdenv phases and explore what’s actually happening.
nix-shell
turned out to have 2 other significant and unforseen usecases. Over time, features were added to support them:
- Making development environments. Rather than debugging a nix build, people would just work on their source code from within the shell.
pkgs.mkShell
was added to support this usecase. - Temporarily getting access to a package. People would use
nix-shell
when they wanted to run something without actually permanently installing it.nix-shell -p
made this much much easier.
When the flakes-centered CLI redesign came along, one of the things people wanted to do was split this up a bit:
-
nix shell
is built for that last usecase (temporary access to a package). All it does is add a package’sbin
directory toPATH
, without any of the development stuff. It also takes multiple package arguments, as that makes sense for this usecase. It’s similar tonix-shell -p foo
when not used for development purposes, as it doesn’t do all the stdenv stuff that makes dev tools work properly, butnix-shell -p
actually does. -
nix develop
takes on the other 2 usecases (debugging derivation builds and development environments). Its argument is still the package whose build environment one wants to enter, and you can still usepkgs.mkShell
to create a “package” with a build environment good for development work. It’s similar tonix-shell -A foo
,nix-shell foo.nix
, andnix-shell
.
So there’s some replication of functionality because we’re in the middle of a CLI redesign which is still experimental (nix shell
and nix develop
are still experimental, so nix-shell
is sticking around despite doing the same thing). There are also some unforseen usecases which we’re now trying to support in less hacky ways.