Hello,
I work on a python project, and I have a flake to get the right environment for it: The python version I use, uv
, and some dependencies I need to link against. The python venv itself I then manage with uv
.
Looking around I see people suggesting to use nix develop
(or what used to be shell.nix
), and especially if you look at direnv
and similar tools, they seem to use that same functionality, often suggesting a setup with a pkgs.mkShell
.
But the documentation of nix develop
clearly says that it drops you into an environment that is ready to build the derivation you referenced. That is not the environment you referenced, but just “on the way” to build that one. In that sense yes, it’s a “development environment”, if you are working on developing a nix package.
But in my case, and many others I’m sure, they just want the right environment to be able to work on their project. Then nix develop
seems to be the wrong thing. Am I missing something?
I’m unsure because it looks like “everybody” is using that. But nix develop
comes with so much baggage that you probably don’t want, like all the shell functions it adds for you to play around with the build phases. Again, this makes sense if you work on a nix package, but not in the case I describe.
In my case, don’t we want to use nix build
and add ./result/bin
to the path?
Please help me get unconfused
If you want to hack on your non-nix code and use the tooling that you’re used to using outside of nix, use nix develop
. If you want to build it with nix and get the resultant benefits, use nix build
+ result/bin/whatever
, or use nix shell
to make it available on PATH, or use nix run
to run your program directly.
Thanks for taking the time.
The options you give make sense to me. If you go the nix develop
way, people use nativeBuildInputs
to get an environment. Then maybe that’s on purpose? I felt like that was a way to get around using the wrong tool (develop
instead of build
). Because instead you could have just gotten that environment to begin with.
I don’t want to reinvent things myself and direnv
seems fixed to use a devShell
… in your opinion, this is the way to go?
Ultimately I think any of the above options are fine, it just entirely depends on your workflow. There’s some overlap in usage and it’s not clearly distinguished in documentation.
Normally I would stick to the nix develop
-type workflow while hacking on the code, because I usually want some additional tooling that isn’t necessarily used to build the package (e.g. some tooling that I’d use to init the project, maybe a language-specific formatter) - and yes, I use direnv
which essentially forces that workflow, but it works for me.
Once the non-nix code is in good shape and I want to add it to a config or something, then I would write a proper package expression for it and then expose that.
You can add the nix-packaged version of the current project itself to the mkShell
environment, if you like that way of working. If you do that, it prevents dumping stuff in $HOME
, as all the dependencies and build results will come from the nix store instead. With direnv
it would even result in instant rebuilds if you change the code. Though I personally don’t usually work this way.
1 Like