NixOS package management with Home Manager and Flakes

Long time Ubuntu and Manjaro user here.

I’m scoping out NixOS from a distance, reading the official docs as well as community documentation. I’m also playing with the NixOS demo appliance.

I understand the default NixOS package manager is used for system-wide installations whereas Home Manager combined with Flakes is for installing packages for specific users.

One scenario clear in my mind where using Home Manager and Flakes is advantageous over system-wide is for reproducing custom packages in a development build environment.

In my experience developing Django projects with Python, I establish my virtual environment with required packages using pip and when I deploy to my Heroku slug in prod, the packages are exactly the same as my local testing venv. My Python virtual environment packages are also sheltered and distinct from whatever system-wide packages may be installed with AUR in my local Manjaro environment. There are other tools that other developers can use to keep their development environments reproducible such as with their packages listed in Cargo.lock, go.sum, or with JSON/TOML variations depending on the language and platform. NixOS’s Flakes and Home Managers serve this same purpose for developers. I think I understand that much so far.

Since I am not a Gnome developer, testing recent changes being made with other contributors in the latest experimental branch(es) upstream in the Gnome GitLab repo is unnecessary for my use case. Therefore, I would think that using Home Manager / Flakes to handle my Gnome packages is unnecessary. Using the regular package manager and leveraging the official NixOS wiki entry for Gnome at GNOME - NixOS Wiki would be better in this situation. Is that correct?

Right now my development projects and research involves:

  1. Python for data analysis in Jupyter Notebooks using pandas, matplotlib, and seaborn. Currently I use Anaconda which handles the required packages which are separate from whatever similar Python packages are installed natively on my Manjaro distro.

  2. Learning algorithmic software design primarily also in Python which I am able to accomplish without even a virtual environment. All I need is my Python interpreter (>= v3.10) where I edit my source code in VS Code.

  3. Writing more Django web apps, although instead of Home Manager I could continue with my previous development environment technique using Python virtual environments and pip.

This means I don’t really need a reproducible Home Manager / Flakes development environment for my use case for now I guess.

Are there other use cases for NixOS users/admins to leverage Home Manager / Flakes even for non-development purposes? What other scenarios could it be helpful to install packages on a per-user basis?

I would consider yes/no to flakes and yes/no to HM as fairly orthogonal decisions, they’re not coupled at all. I would also propose that you would benefit from studying the possibilities offered by devShells, as it offers an IMO satisfying answer to many of the implicit questions you have and can be repo/project specific rather than user/machine specific, and even consumed by folks using Nix-on-not-NixOS. You yourself could use that as an adoption path from Manjaro if you wished.

It’s sort of easy to disregard some of the designs when you’re the only human who uses the machine and you of course have full rights everywhere whenever you choose. That’s not even terribly specific to Nix, but usually applies to lots of security tech.

It may not apply for you but one distinction is that home-manager, when used without the NixOS module but as standalone, can be self managed by a user with no root/sudo access without granting them such, where if you gave them nixos-rebuild access they can do unlimited escalation and harm equivalent to sudo. That possibility has human-trust implications that need to be well understood IMO.

Another example for per-user package management is that my preferred version of some specific binary may not actually match on a neighbor’s preference for that same program. Nix design means we don’t have to compromise or unify, we can both have it our way. Homebrew or apt would deny this. Examples might include running different versions from one another, one of us supplying a custom patch to the build, or especially pertinent for wrapped programs like Neovim where the content is a very personal-taste thing. Sort of the same reason you probably wouldn’t define system-wide shell aliases or functions for something intrusive like replacing ls with eza as a global default - it avoids collisions and reduces unpleasant surprises while still allowing individual users to express their desires in their own space.