Depreciate the use of nix-env to install packages?

Yes, probably. On a multi user host, nix-env would also be a way for unprivileged users to install packages.

The big problem with nix-env is that there is no alternative for it at the moment short of using home-manager (which is a completely separate project with its own drawbacks and reasons why we wouldn’t want to officially endorse it as the blessed way).

You can do declarative package management with nix-env, but it requires adapting an essentially custom solution and is not a good fit for new Nix users:

I think we could reasonably improve nix-env, migrate it to be more declarative and eliminate common gotchas, but the discussion of such things is usually dismissed immediately because Nix upstream doesn’t want to touch the (stable) nix-env in any way, as work is already underway on the new Nix 3.0 nix profile CLI.


I’ve been using nixOS for about a year. I love the declarative nature of it.

It has taken me most of that year to discover a pattern for declarative management of my user packages.

I list my user packages in a flake output such as

packages.${system}.default = with pkgs; buildEnv {
  name = "desk_default";
  paths = [ git-annex rage self.doomemacs ];
  pathsToLink = [ "/share" "/bin" ];
  extraOutputsToInstall = [ "man" "doc" ];

This was installed by nix profile install. Whenever I change the flake, I run nix profile update 17 to update it. So far I’ve not noticed any problems with this approach, but I doubt I stress it much. The few gui apps I use are installed by my nixOS config; I do not know if nix profile would conflict.

Ultimately I am looking for a simple, declarative way to specify user packages for multiple machines. Being able to declare project tool dependencies in a project file is another important goal – especially to get team adoption.

My current best practice is using a Dockerfile to specify a project toolchain. While the Dockerfile is so much better than README instructions, using flake.nix might be that much more reliable.

1 Like

I think this is an unpopular opinion in the Nix community, but I really like nix-env.

It is nice for tools that you use occasionally, but don’t want to bother running a nix-shell for. I personally like that things installed with nix-env don’t get automatically updated when you run nix-channel --update or nixos-rebuild. Sometimes I like to stick with specific versions of packages in nix-env, even if they are older (or newer) than the channel I’m currently on.

I am generally okay with the fact that the environment I setup with nix-env is imperative and non-reproducible.

I feel like “bad habit” is a little strong. There are a bunch of ways of installing packages, each having pros and cons. nix-env is one way of installing packages. Like pointed out in this thread, it has a bunch of surprising behaviors, so it may not be suitable for new users. But if you’re familiar with Nix (and especially nix-env), it can be a nice tool to have in your tool-belt.

Although maybe you’re specifically talking about newer users, in which case I may agree with you. There is certainly a trade-off between asking new users to jump into the deep-end and do everything completely declaratively (NixOS / home-manager / nix-shell), verses giving them an option to use a tool that sort-of works like they’d expect coming from another distro (nix-env?).

Purely anecdotal, but I’ve seen at least one company that has adopted Nix because of the ease of installing things with nix-env. Nixpkgs just has so many development tools, it can be really helpful for a company looking to setup a semi-reproducible dev environment, even if they have no interest in building their own projects with Nix. (Although nix-shell would be another good option here)

It would be really interesting to see some data on how many people got into Nix by using nix-env as a gateway drug, vs people that just got completely turned off of Nix because of the quirks of nix-env.


And we should make that clear without value judgement.

What are those reasons? I always thought it should be integrated much more tightly into the ecosystem. Exactly for the reasons you named why it is cumbersome to use nix-env for declarative environment management.


I like the approach under “Declarative Package Management” in the nixpkgs manual. NixOS - Nixpkgs 22.05 manual


Well home-manager is a downstream project, to really endorse it, we would need to make it an upstream project (i.e. merge it into nixpkgs probably), since at the moment nothing is preventing a nixpkgs commit from breaking home-manager (it probably does so occasionally).

And upstreaming home-manager is nontrivial, I think, since you’d need to, for example, figure out how to eliminate the code duplication between nixpkgs nixos modules and the frequent reimplementation of said modules in home-manager for user services.


Alright. Yet there is still a viable intermediate step of just telling people in a prominent location that it’s fine to use home-manger for declarative users environments.

And I didn’t intend to suggest that the imperative approach be removed or anything, though my wording could have been clearer on that. nix profile is surely sticking around, even if nix-env should probably disappear at some point due to its semi-broken nature.

What I have a problem with is that the imperative approach is effectively raised above declarative approaches by being the sole method distributed as part of nix itself. Nix-standalone needs a declarative package management system that works easily for newbies out of the box, and is presented in documentation as a suggested way to manage packages with nix, if not the suggested way, with the imperative system being secondary. It would help if the default config file structure allowed “dumb” cut-and-paste substitution between it and environment.systemPackages / home.packages.

nix-env -iA is currently seen (by newbies and outsiders) as THE way to install packages with nix, and that really needs to change.


Distrowatch’s webmaster jessie reviewed NixOS 22.05 and had many issues (link to the review)

I was surprised to read about nix-env in multiple places, and as the author had issues such as bad desktop integration, I wonder if this could be related to the use of imperative package management instead of declarative global wide?


but it took a few minutes for Nix to search for a package.

Yes, but just because nix-env is broken and they didn’t come across the warnings that you need that pesky -A flag, not because imperative management is inherently broken.

Still a shame that they had this experience. It’s silly, but will probably persist until nix-env is abolished by nix profile.

I suspect a fair few of the other problems might have been legitimate issues with specific packages, but I don’t personally use plasma.

If I read the documentation correctly, nix profile is still experimental, right?


Yep, it’s part of the nix 3.0 CLI work. There’s a rough roadmap for it here: Nix release schedule and roadmap

Sadly, it looks like it might be many years until that particular set of problems caused by nix-env is fixed, unless there is appetite for adding a warning when -i is used without -A or something.


I also agree Nix should officially support a home environment configuration tool. Guix now has Home Configuration (GNU Guix Reference Manual)


I won’t defend the use of nix-env or nix profile, especially on NixOS, except to say that these are pretty essential tools on non-NixOS systems that allow users to migrate from other package managers.

On non-NixOS systems impure global installs are a huge draw for VMs and some CI. Which I’d argue is a legitimate use case for them. I can spin a reproducible worker for almost any distro without much effort. I don’t have to depend on something like home-manager, or nixos-darwin, and I don’t have to add any wonky homemade hooks to my .profile to get those boxes to have certain tools available.

But the real use case is: there’s a 0% chance of me convincing people at work to adopt Nix without a rough equivalent for apt install or brew install. For folks that don’t know much about Nix these allow them to use packages built by Nix without sending angry emails and rallying a mob to hunt down the DevOps engineer that sold management on this incomprehensible tool :rofl:

They are a necessary footgun. And yeah it’d be nice if we could be rid of them, and the UI surrounding them is icky - but for new users the “good UI” has a bigger learning curve.


This is a very good note :slight_smile: I think the important take away is that the documentation should be very clear about the potential footgun, and give users all the information they need.

I still think the mentions of these footguns on the wiki pages with little additional context do more harm than good, though.


Note that it is also not impossible to have a declarative approach and an imperative interface: I. e. nix-env -iA, nix profile install could just modify a config file which describes the current user environment and then immediately apply the changed configuration.


Indeed, gentoo does this to a degree with it’s world concept. It wouldn’t be unreasonable to take a similar approach with nix, though that would mean reworking nix profile somewhat, and it’s probably too late for that at this point.

It is experimental, so it’d certainly be possible.

At least for nix profile that is exactly what already happens, but looks entirely different from what one is used to in the delarative approach. It’s also a bit hidden in the inner workings, and not advertised, as opposed to say /etc/nixos/configuration.nix or ~/.config/home.nix.

1 Like

If it’s to be compatible with declarative usage, though, it would still need some changes. Currently the only way to edit the declarative definition is to use the imperative commands, since it’s stored in the nix store as part of the derivation.

Hosted by Flying Circus.