What would you like to see improved in Nix cli experience?

Hello :wave:t3:

I’m currently tackling a few UX issues I can’t stand with Nix, such as 7461 or 7462 (unhelpful warnings).

IMO, this kind of messages are driving potential Nix users away when the first encounter they have is made of puzzling warnings… So, let’s improve the situation :rocket:

If you have some puzzling situations when using nix (I’d prefer dealing with code evaluation warning/errors separately), let share them here or/and report them on Nix GitHub project, so we can actually improve them :beers:

  • During the evaluation of flakes a pethora of custom output attributes have evolved, which cause warnings on a nix flake check. There should be a way to silence certain warnings or to modularize/extend the check system to allow for custom checks (Extend `nix flake check` to support custom attributes · Issue #6453 · NixOS/nix · GitHub)
  • Some commands “expand” a flakeref to a store path, and fail if that doesn’t exist. They should be smart and build it, eg. nix copy

Not directly nix related but tightly fits the ecosystem:

  • An equivalent of nix-collect-garbage that only removes profiles, but does not do an actual garbage collect
  • A flake compatible nixos-option (or generally usable with 2.4, regardles of flakes or not)

I’d like nix-collect-garbage (and, for that matter, nix-env --delete-generations) to have a way to keep any generations that are in the $n most recent OR that were replaced less than $d days ago.

Currently, nix-collect-garbage only supports the time-based form afaik, and nix-env --delete-generations allows you to do either, which means you can AND them (the preservation conditions, that is) by running 2 commands, but you cannot OR them.


nix-env tools should be deleted from existence and from history… maybe that’s a little harsh.


More reflection affordances would be cool, for instance it’d be neat if you could just nix repl <flake> and have self bound to the flake in the repl. Then you’d be able to explore the outputs, which in the NixOS case would include self.nixosConfigurations.<machine>.config etc.


Nice! Some of my nightmares:


The unification of flakes-cli and non-flakes-cli under nix-command is probably a bad thing. There are very significant differences between nix build -f . foo and nix build .#foo, and the fact that they share a CLI is something I find very strange.


well, if you think that’s strange ,look at trying to pick a name for nix shell. naming stuff is very very difficult.



Incidentally, I just opened up this issue today:

I realized that nix develop creates a derivation which there is no way to reproduce in Nix code, and thus there is no way to have other derivations depend on a dev env, even though I feel this is a valid usecase (scripts that first enter a devshell, etc).

Another consequence is that there is no way to build the actual devshell derivation without also running it, which is bad for things like CI and caching, unless we have some kind of special handling for devshells.

I think a simple primop like builtins.devEnv drv would solve this, but in general I don’t think the CLI should be doing any special “magic” like this that cannot be reproduced easily in Nix code.

Another similar situation would be the eval-cache, which is heavily tied to nix build and flakes and doesn’t even work with things like nix eval which is completely unintuitive. I think the solution there may end up being similar to my suggestion for the above issue (a primop):


i never use these shells in CI. It’s always nix builds or the nothing…

Shells != Builds , I have the luxury/privilege of not supporting legacy garbage.

But anything that could improve the situation …would be super dooper!

in terms of the underlying abstraction shells == builds in that they are both derivations. The only differnce is that one can be referenced and one cannot (which I think is a mistake).

For example, at work we have a very sensitive tool (SBT) that is very finicky about its environment, and even a slight deviation can cause some unexpected behavior, what I do in CI to prevent this is to enter the devshell produced on the build of the project package we are going to work on so that the environment SBT is operating in is identical to the build env, which is already known to work reliably.

I updated my issue with a concrete example to properly illustrate what I mean, but, yeah, the general comment is that the CLI should not do things that cannot be done manually in Nix code. It should be a convenience, not a crutch.

1 Like

if you talking about Scala build tool, ouch… that things is about a reproducible as a making a sculpture out of water.

Java, and things associated with it seem to be the most unreproduable things i’ve encounted… … if SBT is something else…then I’ve fallen into the too many acronyms doom trap.

Sure, I can see what you mean… i loose track, but i think nix now has 600 shells now… :wink:

Interesting stuff, thanks for the education.

And exactly here the misconception starts. It does not create a “derivation”. It just mimics an environment that can be used to build a given derivation.

And as pointed out in How to use `nix develop` within a GitLab CI pipeline? - #2 by NobbZ, it is possible to use nix develop in CI.

CI Services that allow you to change your shell for a job/step with a custom command, can use nix develop even as a “shell”.

Though you will never actually able to “build” and “install” something that is like what you enter with nix develop, as it simply isn’t able to set env vats some how.

Anyway. Most if not all of the posts since What would you like to see improved in Nix cli experience? - #10 by nixinator are probably off topic in this thread, and I’d ask @moderators to split them out.


I’m gonna have to beg to differ. Simply do a nix develop --profile foo and inspect foo, you’ll see that is a unique derivation. In any case I think thufschmitt has the right idea as to how to address it.

I actually have an ad hoc 2nix style solution that generates a lock file which is then used to build a local maven repo that SBT exclusively reads from, so its a little better than what’s out in the wild as it has no IFD and no massive FOD. I wanted to do a proper 2nix or a dream2nix integration for it, but haven’t had time yet.

Agreed, I was just trying to use a few examples to illustrate the general idea that the CLI should keep magic like this to a minimum, sorry for derailing :sweat_smile:


This isn’t precisely a CLI thing, but I’d like the ability for nix to keep track of how long it’s been since a store object was tied to a gcroot, and allow gc to be configured to use that information to decide whether to delete it. It would help a lot with the issues people have with, e.g. nix shells being garbage collected when they don’t want them to.


It would indeed by nice if the garbage collector could delete the least/oldest used derivations first


Very annoying and easily fixable:
nix eval nixpkgs#hello fails with a long, cryptic error.

1 Like

Fits the title, but not really the context of the initial post. Here’s it anyway:

  • A reduced set of pocelain nix
  • A consistently behaving set of plumbing nix

Here are some basic things Nix needs to get right imo, many of which are nicely implemented in Guix (anyone thinking about the Nix CLI’s UX should spend some time messing with Guix)

  1. We need a unified subcommand interface, and subcommands must have individual manpages, like with git.
  2. nix install <package name> and nix remove <package name> should both just work and do what people expect.
  • no subcommands required (this can be an alias for nix profile install and so on, whatever)
  • if a flake is unspecified, assume Nixpkgs or allow users to set a search path
  • only direct users to specify a flake or individual installed item if the name given is actually ambiguous
  1. Incorporate something like nvd to show the changes between generations. The ability to (p)review changes in that way will be taken for granted, if not seen as table stakes, for users coming from anywhere else.
  2. Repurpose nixos-rebuild as plumbing (or replace it, whatever) with a new nix os subcommand or similar. (see: guix system)

I can think of other things, but I think just those would go a long way, especially with new users


These are deep changes in Nix, I suppose this would require a RFC or something

Hosted by Flying Circus.