What is a good setup? How to learn?

Hi, I’m starting using nix as a package manager. I starting using nix-env -iA and using nix-shell inside projects.

The idea is to have a system wide package manager (where, for example, I will have Python 3.11) and projects with a shell nix that will have other packages (e.g. python 3.10).

I do wonder if there is a better way, maybe using flakes? I see home-manager that you could have a system wide management of your config in a profile and then use the flakes as some sort of nix-shell I’m currently doing.

Is there a way to have system wide packaged installed in a profile like how home-manager does it, without using home-manager? I want to learn how to do that to understand better how home-manager works. I was thinking on create a nix-shell and source it on every new terminal (zshrc source as first line) but I don’t think that’s the best solution.

I hope you can help me on figuring out. Thanks!

Uh, nix-env is cursed and only good for special use cases. Having a “nix-shell that is sourced in each terminal” is pretty close to what home-manager does. You can install it without using flakes (but using it with flakes is actually a bit easier). Home-manager will not introduce any changes unless you explicitly tell it to, so installing it doesn’t hurt.

If you search in this forum, you will find a lot of “how to get started” discussions. :slight_smile:

Thank you. I’ll check in the forum for good learning resources:D

Yeah, I read that it was not a good idea go with nix-env. I know that with home-manager I just need to do a “switch” to get a new state of my system. My idea with nix-shell was to have a default.nix with all my packages system wide and source it on my zshrc. That will make my system to enter into a nix subshell every single time. Then, if I need things in a subproject, that folder would have a shell.nix and I just need to “nix-shell” there to get the packaged I need. In that process, the packages would take precedence than my global ones.

The latency of entering the nix shell on each shell launch is not optimal or necessary. It’d be just as well to simply use home-manager, and enjoy the declarative service support as a bonus.

1 Like

Yeah, that’s why I think so to. But, how is that managed by home-manager? Is all about a profile? That’s mostly what I want to understand :thinking:



I’ve seen things. I’ve been seeing things. 12 hours into a call.

@OP: For a serious answer, I recommend not using nix-env at all. (We’re actually working on removing recommendations to use it from the documentation). If you’re on NixOS I recommend using home-manager as a NixOS module and declaring what you want to install “system-wide” (though in this case there’s not really such a thing, because it will simply be “installed” into your user’s nix profile).

If you’re on non-NixOS Linux or macOS, you can just put the packages you want available in a particular directory into a default.nix or shell.nix there, and either manually execute nix-shell in those directories as needed or use direnv. In practice this is usually better than the “global” method; if you have a directory tree like ~/projects, you can put a shell.nix in there with Python 3.11, and then in ~/projects/my_py310_project you can put another shell.nix with a different Python version, and when entering a nix shell within the child directory, 3.10 should replace the 3.11 from the parent directory.

Thank you for this link, pretty useful :smiley:

1 Like

Thank you for this. I’m using Linux and MacOS.

So, let’s say that I want fzf everywhere on my shell, I thought nix-env would be the solution (and sort of, it is, but not recommended). About the nix-shell with direnv is what I use currently. My doubt is more on how could I have defaults on all the system (just having fzf everywhere I navigate).

This is really giving me good insights. Thanks for all the help.