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.mkShellwas added to support this usecase. - Temporarily getting access to a package. People would use
nix-shellwhen they wanted to run something without actually permanently installing it.nix-shell -pmade 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 shellis built for that last usecase (temporary access to a package). All it does is add a package’sbindirectory 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 foowhen not used for development purposes, as it doesn’t do all the stdenv stuff that makes dev tools work properly, butnix-shell -pactually does. -
nix developtakes 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.mkShellto 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.