Difference between nix-shell/nix shell/nix develop

I’m quite new to the wonderfull nix world and wondering what is the difference between the ‘nix-shell’, ‘nix shell’ and ‘nix develop’ commands.

From what I know, nix-shell is the same as nix shell but older and using nix channels instead of flakes.
In my mind nix shell was the exact same as nix develop in the sense it opens a shell with packages installed as specified in a flake.

I ask because I noticed that nix shell and nix develop commands does not open shells in the same way:
If I lauch for example nix shell nixpkgs#hello, the result is a shell launched with the hello package installed and my actual shell (zsh) still have access to my shell config.

On the other hand, with a small flake like that:

{
  description = "Build Shell with any dependency of the project";

  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.nixpkgs.url = "github:NixOs/nixpkgs";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem
      (system:
        let pkgs = nixpkgs.legacyPackages.${system};
        in
        {
            devShells.default = pkgs.mkShell {
              nativeBuildInputs = [ pkgs.hello];
          };
        }
      );
}

If I run nix develop in the flake folder, I have also a new shell with the hello package installed but all my config is gone and I’m back with the default bash.

Questions:

  • Why is there no trace of my global config with nix develop but not with nix shell ?
  • What is the difference between the two ?
  • Why the flake I showed before does not work with nix shell #. ?
2 Likes

The way I conceptualize it, nix develop is sort-of nix build --interactive or nix build --debug — it creates a build environment for a particular nix package, but, instead of automatically running build phases, it drops you into a shell in the build environment, so that you can debug the build itself.

nix shell “installs” requested packages into an ephemeral shell environment.

1 Like

Okay, so I’m using nix develop the wrong way. I use it in my dev projects to have the same dev env on all my systems but I should be using nix shell instead

No, that is the correct way to use it. It is a bit confusing, but nix shell just pops whatever packages binaries you specify into a shell, whereas nix develop is more involved and allows you to setup other aspects of the environment, such as variables, etc, which is useful for reproducible project devshells.

1 Like