Defining multiple nix shell environments


I’m relatively new to nix.
My first goal is to simply provide a nice development environment for developers to build and run code.
At some later stage, I can then package our builds with nix.
I’ve converted my to a flake.nix.
So one issue that I ran into is that we actually need separate shell environments for build and run.
For example, when building I want to include for the include headers, but for running the application, that library should not be present (as some of the tools appear on the path and cause version errors with our application).

So I’m trying to figure out how to define the right outputs in my flake to be able to start either the “build shell” or the “run shell”.
When I had only a single environment, I defined it using this snippet: Flakes - NixOS Wiki

Like many others I’m confused about whether I should be using nix develop or nix shell.

From "Lighter" and "cleaner" shell for `nix develop` and `nix shell` · Issue #4609 · NixOS/nix · GitHub , it sounds like I should be using nix shell but it just doesn’t seem to work correctly for me.

Here is a tiny example:

Here nix develop seems to do what I want, but how would I use this with nix shell.

As you can see when I run the nix shell command, the command does not seem to be found in the environment.
I’m happy enough to just use nix develop for now, but I really would like to understand things a bit better.

nix develop is for development environments. nix shell is simply for temporarily getting some program into your PATH. It literally does nothing else.

You misunderstand what nix shell does. nix shell does not use the devshell in your flake. nix shell will create a shell with whatever packages you give it. For ruby: nix shell nixpkgs#ruby. Since you want to use two devshells, you should use nix develop and specifiy which devshell you want to enter.
devShells.default: nix develop, nix develop ., or nix develop .#default
devShells.buildShell: nix develop .#buildShell

1 Like

I hope they make it a little less confusing, because when you say " nix shell will create a shell with whatever packages you give it", that feels pretty close to what I want. I want developers to have a shell to work in, with the correct tools and libraries available. I guess the difference is that mkShell does not produce an application.

Anyway, I appreciate the insights.
nix develop seems to work well enough for my use case.

nix develop is what you want. nix shell is imperative, whereas nix develop will make shells as defined by a flake.