I love the idea of nix but the inconsistency and developer experience is terrible. I want to suggest people use it but there is too many rough edges currently.
For example, if you want to install a package the old way, you'll install it including the channel:
nix-env -iA nixpkgs.ripgrep
but then if you want to remove one, you don't reference the channel:
nix-env -e ripgrep
You have a similar issue if you want to use the new `nix` command. To install a package you'll do:
nix profile install nixpkgs#ripgrep
but running:
nix profile remove nixpkgs#ripgrep
will do nothing. It won't say "I didn't remove the package" or "package not found". It just returns silently. The only way to remove it is to point to the number from `nix profile history` or the actual path.
It is unbearably slow:
> time nix-env -qaP ripgrep
nixpkgs.ripgrep ripgrep-13.0.0
11.17s user 2.70s system 73% cpu 18.970 total
Overall I love the idea but it has a long way to go in developer experience and quality before it is ready for any mainstream adoption.
> I've never really understood the use case for nix-env.
If that's the case, perhaps `nix-env` shouldn't be mentioned as the command to use to install packages on search.nixos.org?
I checked the NixOS manual right now but the last time I did, it instructed to use nix-env to install packages. The declarative package management using configuration.nix wasn't highlighted before as it is now.
This is exactly the kind of thing the parent comment mentioned. I'm not willing to go through these kinds of papercuts to get whatever NixOS has to offer with its radical changes.
Oh, and the nix package manager is still unbearably slow. It reminds me of my (unpleasant) time using dnf. Once you're used to package managers like apk and pacman, its an extremely jarring experience to stare at your screen and wait for a package to get installed.
> If that's the case, perhaps `nix-env` shouldn't be mentioned as the command to use to install packages on search.nixos.org?
Yes, you should pretend this command doesn't exist.
There is no need to be using NixOS to do so.
> Oh, and the nix package manager is still unbearably slow
This doesn't match my experience so I wonder what you're doing differently. It's only slow if you're missing the cache, either local or remote, as then you need to build things locally, unlike apk and pacman which install only prebuilt packages from repositories. Nix is fundamentally different to those package managers. I find it very snappy.
My experience is also that it is quick as long as the package is cached. And it usually is unless you are using master, which is definitely not recommended.
I once spend 2 hours on trying to get a newer version of nodejs on my system. Turned out that I had used nix-env a while back to install it and that had priority over the rebuild-switch :| So, I agree. Very risky way of managing nix
nix-env has been easier to use for a new use compared to having a configuration.nix, using home-manager etc, but once you start using any of the latter then just remove everything installed with nix-env (and use nix-shell for one-offs).
for those one-off times I want to just jump into a shell with, say, ranger available, it's as simple as
$ nix shell nixpkgs#ranger
if I am starting up a project that needs a tool, I just throw together a simple shell.nix in a folder for the project and run
$ nix shell
from that folder. there's ways to set it up so you automatically switch to a shell with the specified packages (iirc with direnv just like you'd do it for python venvs) but I haven't felt the need yet.
Yes. (Docs at https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3....) Although it won't "throw it away" in the sense of uninstalling it; it's just that when you exit the shell, you'll be back in an environment which doesn't have the symlink to `ranger` on the PATH.
It basically garbage collects it (you can run it through a periodic service, or call it manually). You also have older versions intact, so you can simply change back to a previous version instantly.
Also, this is the only package manager where I could reliably install gnome and plasma, and have it removed to the last package - pacman and everything else will leave behind random files all around the place.
Well, it can’t help random spamming, but home-manager actually can help here! You can have a declarative config for your home dir and it will symlink config files into your .config folder. Also, it will by default never overwrite any file, but it will ask you to remove spammed configs over which you want to use your own, and since these are symlinks, they are read-only so no program will change them (which is good and bad, because it means programs can’t be configured through their gui settings for example)
it's really useful if you work on projects that need different version of dependencies, as you can define on a folder basis what jdk or python versions you want to have. You can even commit this to git so that everyone has the same env locally
For non-nix usage, I use a docker container with debian in such cases. Just docker run, apt install, keep using while needed, then stop and rm the container. Works great to keep the main OS clean.
It'll still be there, but the symlink will go from your path. The nice thing is that if you open another shell and use it again, it's already there, and the symlink is reestablished. If you want it installed globally then it's still there and it just gets added to your path.
If you start to run our of disk space, then a quick garbage collection will remove all unused packages and builds.
The other nice thing about the nix-shell is I can incorporate pip into it (and probably other package managers as well, though I rarely use anything other than Python). So I can open a shell, add various lib type dependencies and any Python packages I want. All of it is only available in the shell, and when I exit they're gone as far as my OS is concerned.
You could clone a repo that contained my default.nix file, jump into a shell and be working with and identical environment to mine.
I tried. I didn't feel like spending days learning their custom config language just to install a program I want to use. Ease of use is not a label I would apply to NixOS.
Try NixOS with the new redesigned command line. It's much simpler. No idea why this is not getting advertised more widely, as it's been worked on for a few years already: https://github.com/NixOS/nix/issues/779
For example, opening a temporary shell with, say, GIMP, is as simple as: nix run nixpkgs.gimp
If you want to check what packages are available for GIMP, because you are not sure what to run: nix search gimp
I tend to forget very convoluted commands, and I find the new nix much simpler than pacman or apt.
It's kind of nice. So everything in nix revolves around /nix/store
This is where each package is stored in a form <hash>-<package name and version>
The second part is only useful for humans and is not really necessary. The hash is computed from package source, compilation flags, dependencies, architecture etc. (there's also experimental mechanism where you can use hash that is computed from the contents of the package, which solves some important problems).
The reason why hash is used, is so you can be able to have not only multiple version of the same package, but you can also have even the same version that maybe even depend on a different package.
For example in a traditional system you could have situation that you need to run two apps, but each of them perhaps depend on a different version of openssl. That situation is generally not possible with some kind of tricks, you either have to recompile one application to use the same library or you will have do some kind of tricks, like compiling statically, or placing openssl in some other location. In Nix you can have two openssl side by side and each package is referencing the one it was compiled with.
The store also is designated that it supposed to only adding packages or removing, you no renames and definitively no changes of the files there. If you do that (well it's linux, you can also change permissions and do that if you really want to, but you're asking for problems)
Now this makes caching easy. Because when you need an application you not only know its name, you know down even to compilation of the flags what it needs to be. So you can simply compute the hash of it. So when it is needed Nix will first check /nix/store. If the package is there, success, you use it, if package is missing, nix can contact configured cache (which can be even an S3 bucket) and check for the package. If package is there it'll download and extract it in your store. If object is missing in remote cache, then nix will begin downloading source code and compiling, because that's how every package is defined (how to build it).
Now that explained the basics, when you invoke nix-shell to enter. The Nix will perform these steps, it'll check if you have the package in your store, if it is missing it'll download from cache, if it is missing in the cache it will begin building, if another dependency is needed it will do that step to it recursively.
Ultimately when the package is present nix-shell will enter a shell, with modified PATH that includes the package(s) that you referenced. You exit the shell you land back in old shell with old PATH. If you use nix for development you can also combine it with a tool like direnv, which can make it so when you cd into a project directory it will ensure that your dev tools are automatically available. And they will disappear when you exit it.
If you were paying attention you might realize that this approach will generally make /nix/store just continue to grow, the new packages are being added all the time. This is especially when you use it for development and you're changing your application, you will get tons of versions of the single app. That indeed is happening and is kind of a drawback, but there's a garbage collection method which you can invoke manually, or you can also schedule it to run periodically. There is also an option (I think more useful for a build machine) where you can specify how much disk space you want to use it, and it will just clean old stuff as you're hitting the disk usage limit.
Anyway, changing PATH is what nix-shell does (originally author said it was meant for debugging (you could enter shell that was used for building the application so you could troubleshoot why build is failing), but it turned out a great feature of its own). NixOS on the other hand works in a way that you have central configuration system where you have a configuration.nix file with all system configuration. When you invoke nixos-rebuild command (typically called with switch parameter to immediately switch to the new config) the NixOS actually is rebuilding the entire system from scratch, the only reason it does not take so long is because all needed files are mostly already in /nix/store and all NixOS needs to do is to recreate symlinks in the root to point to proper packages. This is great, because:
1. you get system exactly as described, unlike SCM like saltstack, ansiblem chef, puppet the nix configuration is truly declarative, and not just imitation of it. For example if you define a package in the configuration file and configure system, then remove that package, after rebuild that package won't be referenced anymore and available (it still will be in the store, but it would be just taking space that you can reclaim with GC)
2. because symlinks are used, and packages aren't replaced in-place. You can actually make a rollback. Let say you have your system running and you want to try Wayland. You make changes to the configuration to install it, maybe the process failed for some reason or you realized you want restore things back to where they were. You can just revert to a previous version. This also will be a very quick process since you likely still have your old packages installed and nothing new needs to be downloaded.
It's really a new very different way of thinking about packages and about OS, and this approach solves so many problems with the status quo we have right now. Also, removes need for the SCM tools as mentioned above.
Yeah, this could be a NixOS vs every other OS problem. Even when files are declared it was my understanding that `nix-env` was the way to install the file?
Yeah, I think its things like this that make it hard to adopt nix. If you search for a package on search.nixos.org it tells you to install it using `nix-env`.
All I want is a way to say "I want jq, kubectl, and terraform installed" and have it available globally. Not for specific projects or anything like that.
Right now I maintain a makefile that installs everything for me using `nix profile`:
Which almost exactly like I want. Only issue is sometimes a new hash is generated (which I don't understand.. maybe a config update in the repos?) and the makefile can't run anymore:
error: packages '/nix/store/y65pp5hipid0fzxl1z7xjxdk4h9jwfw7-exa-0.10.1/bin/exa' and '/nix/store/gy0bqcs9mcan8af47wakdylhal67dpy4-exa-0.10.1/bin/exa' have the same priority 5; use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' to change the priority of one of the conflicting packages (0 being the highest priority)
I've avoided home-manager because it says:
Unfortunately, it is quite possible to get difficult to understand errors when working with Home Manager, such as infinite loops with no clear source reference. You should therefore be comfortable using the Nix language and the various tools in the Nix ecosystem. Reading through the Nix Pills document is a good way to familiarize yourself with them.
If its common enough to warn about it, not quite the tool I'm looking to pull into my environment.
Wow, I have never got that error but I haven't used nix-env much.
Yeah, to be honest familiarity with the NixOS module system doesn't hurt for home-manager. For me it was worth it but I was also just interested in Nix enough to read through the Nix-pills, etc.
Maybe given some time Nix will be polished enough that a smaller time investment will be enough.
Another thing: Yes, even if customizing your home-manager config could lead to hard to debug errors, once it works it is hard to brick and it will most likely work on new Laptops, colleagues machines, ...
That's why for my small at work my colleagues don't have to be as deep into Nix as I am but they can still benefit from the changes I am introducing in a pretty "safe" way.
I think this might be a broader Linux thing: we could probably simplify a lot of things by going back to the assumption that computers will have a single user.
This has been my experience as well. I have wanted so badly to love it and try and introduce it into many different systems to provide consistent tooling but its just too slow. I also found that many people had a hard time picking it up myself included.
For installing a package, you have to specify the package repository. For uninstalling, you don't because you're operating against a separate repository containing locally installed packages. This should be the same for the new CLI too.
Looking at the manual[1], instead of:
nix profile remove nixpkgs#ripgrep
You'd probably need to run:
nix profile remove packages.x86_64-linux.ripgrep
For searching packages,
nix search nixpkgs ripgrep
is faster than
nix-env -qaP ripgrep
But I find the online search UI[2] to be far more superior.
Is there any data on how many people care about said promises as opposed to care about not having an actively hostile and prickly interface? Because I enjoyed tinkering with this kind of thing in my 20s, but in my 40s I just want something that I can use without having to memorize a ton of arcania, and that lets me solve my problem and get back to my actual goals.
I never wake up saying "today I want to install a package on my computer and revel in my extreme knowledge of how my package manager works". I wake up with plans, and installing a package might be necessary to achieve them.
To be clear, Nix's CLI syntax is what it is because of the following requirements:
* Provide the ability to create a new package by extending an existing package definition programatically
* Provide the ability to have multiple variations of similar packages
To satisfy those requirements, you need a way to uniquely specify packages by its precise location of its definition. It does not interact well with apt's model of having a central package repository assign names for every known package.
> "today I want to install a package on my computer and revel in my extreme knowledge of how my package manager works"
Not strictly necessary, but neither is the dismissal of serious usability issues as "well actually, it's this way because of reasons" which basically boil down to "not designed with the kind of use-cases in mind that many users here are saying cause them pain". The idea that you can't remove a package by the same name you added it by is just obnoxious.
Sure there are reasons for it, but the reasons boil down to "screw you users" if you're just trying to use it. And a project which is actively hostile to usability feedback doesn't fill me with excitement to start depending on it.
`nix install foobar`:
There are N versions of foobar. Choose one of:
* nix install foobar.gnu
* nix install foobar.lfs
* nix install foobar.experimental20220104
(pre-formatted for copy-paste)
`nix remove foobar`
You have two versions of foobar installed. Choose one of:
If you pick on every little detail that differs from an existing tool, call it a serious usability issue, and accuse others of “actively being hostile,” “screwing users,” and “being obnoxious” for the sake of it, that’s the end of any reasonable discussion.
Different tools have different use cases, design goals, and priorities in mind. That is in no way a justification for name calling and mockery.
Nix devs seem focused on improving the ergonomics of the new command line, but it’d probably take time to flesh out the details. In the meantime, I think specifying the package source is a reasonable tradeoff given the features it enables.
I also suspect that keeping the package specification the same between installation and uninstallation time is harder than it might look, though. By its nature, Nix identifies packages by the contents of their definition. “nixpkgs#ripgrep” is merely a pointer to the current ripgrep package definition in the Nixpkgs repository. Therefore, “nixpkgs#ripgrep” will likely not point to the same package at the time of uninstallation.
However: I believe that what the Nix crowd is doing is exploring new ways of packaging and deploying software.
It’s quite different from eg. APT and Yum. The upside is quite big. But one cannot expect them to get every little detail right on the first try. I think it’s impossible to do something like this without experimenting. Or doing a series of Versuchs if you will.
Therefore I do not view Nix and NixOS as a polished consumer-grade product. I would not use it in prod as of now. IMHO it’s too early for that.
I won’t even try it on my laptop. I already have homebrew, which is much simpler and works well for my purpouses.
I still find Nix very interesting. I do believe it has potential.
But what will it lead to? Will Nix be able to deliver on it’s grand promises?
Maybe! Or maybe not. Time will tell. In the meantime I’m here on the sidelines, watching with great curiosity.
Nix itself might never become a big player. But even if it doesn’t, I’m certain that many great ideas and practices will evolve from the Nix Versuchs.
In practice, you will either write `nix shell nixpkgs#package` for one-off packages, or will add one single line into your configuration.nix/home-env config file and issue a rebuild.
I think it's good to consider ways in which Nix's UX could be improved.
But I'd draw an analogy to vim or emacs. These have steep difficulty curves to them, but provide a power-user experience. Roughly, Nix is to apt-get what vim is to notepad. -- It'd be weird to try vim but live in insert mode the whole time.
It's not a matter of "no-the-ux-doesn't-suck", but more "if you can get past the rough edges, the things which Nix allows are wonderful".
Guix greatly simplifies things. Like others said for Nix, I really would recommend managing things declaratively in your system config and a manifest file, but the basic cli isn't bad.
guix install ranger
guix remove ranger
guix pull
guix upgrade
guix search ranger
These basics just work how you'd expect last I checked. There is some `guix shell` stuff as well, but I don't use it, so won't be able to say much about it.
What is terrible about explicitly specifying the source of the package definition? Seems like a dramatic conclusion to make based on a minor detail of the command line syntax.
Thank you sincerely for this public service announcement. We might joke about getting "nerd-sniped", but it really can be difficult to predict ROI when choosing which new things merit attention. This glimpse into real DX issues probably saved me (and many others) some real time and frustration.
OTOH I want to encourage those who do have the time and inclination to get involved and improve those things and help reify the good ideas / fulfill their potential.
I really wanted to love Nix and tried my best to ease into it, e.g. using it as a "pip" replacement for Python, then managing dotfiles, etc. Maybe I chose the wrong side of the "flakes schism", but it was so foggy and unclear how one went from "lazily evaluated attribute set" to "an actual system".
I really wish this was written in something even like Haskell or Ocaml, that has actual real language support and tooling. Troubleshooting attribute errors was just not possible and I gave up (GUIX looks awesome, but I can't really use shepherd unfortunately).
It really says something when I found myself looking to Gentoo as an "easier, well-thought-out alternative"...
Basing their killer app, the package manager, on a weird Haskell-like semi-functional undocumented language was a major faux pas of the project in my opinion. Guix is certainly easier to understand and hack, but sadly too "GNU" (i.e. orthodox) to be as useful in the real world as NixOS.
Adopting NixOS means learning how everything fits together as well as learning the quirks of a not very intuitive language. Way too make adoption even harder for everyone on the fence.
>I really wish this was written in something even like Haskell or Ocaml, that has actual real language support and tooling. Troubleshooting attribute errors was just not possible and I gave up (GUIX looks awesome, but I can't really use shepherd unfortunately).
The 3 times I've tried to use Nix (and invariably gave up), I always came to this conclusion.
A language like F#/OCaml with great typing and type inference and good auto completion could get us half the way to usability.
I'm going to preempt this with anything not explicitly forbidden is allowed, lest this come off as "you holding it wrong".
Using the CLI to add/remove package is considered kind of an antipattern in nix. The correct way to write a fair bit of Nix (the language) to install and configure things. That then can be versioned, forked, etc.
There are a lot of really cool parts of Nix, but they're under a ball of rough edges.
Yeah, the hard part is maintaining a file just to have the tools you want is a major hurdle that is not reasonable for most people to jump over. If I'm working I might do something like this:
curl example.com/data.json | jq ...
and I'll realize I don't have `jq` installed. I do not want to open vim, edit a configuration file, and then re-run a command to rebuild my system. I just want jq. I can't change context like that just to get a package.
I understand this isn't aligned with the purity stance that nix has but if they were able to allow this use case, it would most likely get more people doing it the right way eventually.
I can't drink all the kool-aid at once, I really need to replace bits of my workflow at a time and I can't do that with nix currently.
The approach I've laid out in my original comment (using `nix-env`) provides a bad developer experience and makes me not able(willing?) to move forward with the adopting more of the practices. If the initial experience was better, I'd invest more time learning more.
> Yeah, the hard part is maintaining a file just to have the tools you want
I'd be okay doing that to install packages but what I don't like is the N number of ways to install packages. Do I use nix-env? Do I use the new nix CLI? Do I make an entry in configuration.nix? Do I use this thing called flakes which is marked as experimental but almost everyone seems to be onboard with it?
There's no central and definitive source of documentation either. There's the official NixOS website, nix pills, nixos.wiki, blog posts from prominent developers, and other sources I don't remember.
Oh I don't disagree. The onboarding experience is terrible.
* You have to learn a new and kind of knobbly single use language.
* If you are going the NixOS route there's the non-trival learning curve for that as well.
* And the package manager itself is more than a little confusing.
As for the workflow. I use NixOS on my personal machine. I'm fine with it because its typically pretty quick and happens infrequently. Buuuuuuut I wouldn't really advocate for NixOS. Its cool. I like it. I'm never going to recoop the time and effort I spent learning how to use it.
$ time nix search nixpkgs ripgrep
* legacyPackages.x86_64-linux.ripgrep (13.0.0)
A utility that combines the usability of The Silver Searcher with the raw speed of grep
* legacyPackages.x86_64-linux.ripgrep-all (0.9.6)
Ripgrep, but also search in PDFs, E-Books, Office documents, zip, tar.gz, and more
* legacyPackages.x86_64-linux.vgrep (2.6.0)
User-friendly pager for grep/git-grep/ripgrep
real 0m0.514s
user 0m0.494s
sys 0m0.019s
We're trying to improve the UX with the new CLI. Precisely to improve the developer experience and quality. Any other major gripes?
Yeah, the UX for the new search although faster is more of a problem for me. When it returns `legacyPackages.x86_64-linux.ripgrep` that makes me think "oh no, I don't want the legacy package. I want the good one", but no non-legacy package is returned.
Also the name is confusing, it return `x86_64-linux` on linux and `x86_64-darwin` but why does that information need to be included? Then it brings up the problem if I need to install with the whole long string or if I can just install with `ripgrep`.
The other big grip I have with the new CLI is the installed packages. If you run:
> nix profile list
You get a gob of mostly unreadable text scrolling through your screen:
Okay. Looks like there is an issue for duplicate profile entries already; just hasn’t gotten attention. https://github.com/NixOS/nix/issues/5587 I’ll take a look.
The verbosity of “legacyPackages.x86_64-linux.ripgrep” in the search results may be too much. We can omit the default portions or provide the full detail somewhere less prominent.
It's the "-A" that requires "nixpkgs." for installing. It's slower and probably there's other details I'm missing (the complexity rarely makes me want to dig deeper than these bare-basic nix-env commands since I only use it for a couple of things), but you can do "nix-env -i ripgrep".
Actually, -A makes it faster and more precise about what you want to install. The Nixpkgs repository is defined as large associative array containing packages. When "-A nixpkgs.ripgrep" is specified, nix-env looks up the associative array using the key "ripgrep". That in theory should take constant time regardless of the size of Nixpkgs. When -A isn't specified, nix-env searches the entire associative array for a package whose "name" attribute looks similar to "ripgrep." That takes more time as the size of Nixpkgs grows. It's also less precise because the "name" attribute for packages aren't guaranteed to be unique, unlike a key for an associative array. It doesn't do an exact match either, because the "name" attribute also includes version numbers by convention.
For uninstalling, nix-env doesn't have the -A flag, because it has to operate on the set of installed packages, not Nixpkgs.
I just started to install nix and my first impression is the opposite of terrible. The way it describes what it will do in detail, before doing it, I think is _excellent_. Of course, I have not started using nix yet but to me this shows some attention to detail that developers appreciate and that most other tools don't bother with. I am hopeful I will like it.
Funny you say that, because the installer is about the only thing that is helpful like that. Everything else from there is basically "what do you mean you didn't read the entirety of the official manual, and the deprecated wiki, and the unofficial wiki, and the other wiki, and Discourse, and IRC, and random blog posts, and just learn to read undocumented inconsistent idiosyncratic source code already!?"
The installer is absolutely first rate, but I would strongly recommend asking for help at discourse.nixos.org as soon as you start getting stuck (which will definitely happen, probably rather early).
It's unfortunate that this is the top comment, as it might unfairly turn potential users off to Nix. Imperative command line installation of packages with nix is contrary the model of how it is supposed to work, and is deprecated. I've never used it once.
The thing is, it might be contrary to the underlying model of the OS, but it's how a lot of people want to do it.
To give a similar example: in the Rust programming language, dependencies are declared in a TOML file. While the dependencies are declarative, there's also a popular tool (that's being added to the main project) that lets you do
cargo add awesome-thing-rs
and add the dependency to your project, and edits the config file for you. That's it: no combinations to remember, no weird use cases, no unintuitive error messages, you just say "I want to add X" and then X is added.
Is it really that hard to add a word to a list in a config file? If this is what is stopping you, then you haven't yet understood how nix works or the value of nix. You could write a shell script in 5 minutes that would add and remove package names from a nix config file, but that's fundamentally no different from writing a tool to add #define lines in a C header file rather than just manually editing it. It's missing the point.
For me it is a context switching issue. If I'm reaching for a package it is because I was in the middle of something that needed it. I'm not sitting there thinking "What packages might I need some day?".
So if nix could allow me to get the tools I need without context switching that would be a great addition. I don't want to have to go edit configuration files just because I haven't installed some tool yet.
The way I work is I have in my configuration a set of packages that I want to always have access to. Things like git, vim, gpg and so on.
Then for every dev project I have shell.nix defined which lists project's dependencies. I also have direnv installed, so when I enter that directory, the project's tools are automatically available for me. I rarely change the main configuration and more often project's shell.nix. And for one-off's I use nix-shell -p <package>
But I don't want it temporarily, I want it all the time. So I want to be able to make it available for future me too, that way next time I try to use it I don't have to run `nix-shell -p <package>` again
It will still be on your system until garbage collected, so if you decide to install permanently, it will be instantaneous. "Permanent" is a fuzzy concept with Nix in any case, as all it means here is that it's in your path and won't be garbage collected. In this case you just add the package name to an array in your config. It's extremely simple to do, just editing a list in a text file. I understand you want to just run a command, but perhaps Nix is not for you if easy command line usage is more important than automated reproduceable OS config.
That being said, I think there are indeed ways to partially manage your config using simple command line commands but I haven't found the need myself.
Then I would look into home-manager and/or nix-darwin if you are on macOS.
I think under the hood home-manager basically declaratively manages a Nix profile for you. You (or even better a home-manager managed .bash_profile) can then put that profile into your PATH.
I'm much newer user and admittedly the documentation is not great, so I've used forums and IRC a lot and from what I've gathered, the movement is towards declarative reproduceability. This is the reason for the development of flakes. I saw installation of packages using nix-env in many search results and tutorial pages but newer comments seem to indicate that this is no longer recommended, and it fully makes sense to me. I want to get my machine back to the same state using my config checked into git, and installing imperatively using nix-env clearly goes against this.
For example, if you want to install a package the old way, you'll install it including the channel:
but then if you want to remove one, you don't reference the channel: You have a similar issue if you want to use the new `nix` command. To install a package you'll do: but running: will do nothing. It won't say "I didn't remove the package" or "package not found". It just returns silently. The only way to remove it is to point to the number from `nix profile history` or the actual path.It is unbearably slow:
Overall I love the idea but it has a long way to go in developer experience and quality before it is ready for any mainstream adoption.