Is nix develop supposed to be used for creating development environments?

I’ve recently started using flakes for all my software projects to handle building and to handle dependency management. My understanding is that nix develop is supposed to be the flake replacement for nix-shell, which is what I’ve been using to use to get a shell with my project’s development environment.

nix develop works for this purpose as well, but it’s not without it’s quirks. For example, the bash shell I get with nix develop is bash without readline support. I’ve looked into this, I found that these behaviors are all intended:

https://github.com/NixOS/nix/issues/6091
https://github.com/NixOS/nix/issues/4609

I’m a bit confused after reading these. Is nix develop not supposed to used to create development environment?

4 Likes

For scripting languages, using nix develop or nix shell does not make a difference.

What about for compiled languages like C++ or Rust?

I’m not sure what you mean by this. In general, it is simply untrue: nix develop loads the environment described by the devShell output of the flake while nix shell loads the environment specified in the defaultPackage output. In general these could be completely different, in practice devShell tends to include the stuff in defaultPackage and add some extra development tools. This is independent of what languages you happen to be using in the project.

2 Likes

Are you familiar with direnv and how it integrates with Nix?

Very briefly: direnv automatically invokes nix develop when you cd into a project’s directory and layers the resulting environment on top of your underlying shell. Thus I get my highly-configured zsh rather than a spartan bash when working on the project. cding out of the directory automatically disables the nix develop environment.

If I want to have a more pure nix develop experience (without any extra stuff being inherited from my underlying shell) then I invoke nix develop by hand.

edit: OK, I see that you’ve discussed direnv in one of the issues, and that you appear not to have had much luck. Odd, as use flake (today, as opposed to months ago) has, for me, been trivial to set up and use reliably. So much easier and more reliable than just about anything else related to this topic.

1 Like

The workaround of direnv is actually recorded in one of the linked issues: Bash completion broken after running `nix develop` · Issue #6091 · NixOS/nix · GitHub

Doesn’t really solve the problem that nix develop itself doesn’t support this workflow well, but in my mind direnv solves the interactive developer workflow, whereas nix develop is for when you want to test something in a derivation. These caveats make sense in the latter case, so are arguably correctly handled, while direnv exists for the former use case.

Edit: Seems that’s also discussed in the other issue: "Lighter" and "cleaner" shell for `nix develop` and `nix shell` · Issue #4609 · NixOS/nix · GitHub

This makes me fairly confident the answer to

Is no, it’s supposed to help you develop nix derivations. People sometimes use it for development environments too, but arguably that’s misuse. You should use direnv currently, but there is ongoing discussion about handling this use case too.

2 Likes

Are you suggesting some use of direnv (for the provisioning of development environments) that does not rely on use flake (or use nix)? Does use flake not end up invoking nix develop?

But it’s so IMMENSELY useful!

1 Like

No.

Simplified it does source <(nix print-dev-env)

3 Likes

Which is why it works with zsh out of the box and doesn’t cause issues with bash’ features; it’s the same shell process you launched originally, just with a handful of new variables. Also why editors/IDEs can use it too.

You may have noticed that you can still close the shell without going back to a parent using exit, i.e., it doesn’t launch a new process, unlike nix develop :slight_smile:

The downside is that it’s necessarily impure, but that’s usually what you want for a dev environment.

1 Like

Does nix develop do anything significantly different from source <(nix print-dev-env) in a stripped-down shell?