I use nix-shell to test out a package, or use one that I only need temporarily.
If I need a package for a particular build then it gets added to my config files, and I rebuild switch.
If I don't want that package anymore, then I remove it from my config and do another rebuild.
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.
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.
nix-env -e "*" # remove all packages $ 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.https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3...
https://nixos.wiki/wiki/Development_environment_with_nix-she...
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.
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 have no idea why everyone isn't using NixOS.
Well, in my case it is because Nvidia Jetson's line of products is forcing me to run Ubuntu.
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.
Documentation has also matured a lot, see: https://nixos.wiki/wiki/Resources
Because NixOS is a valid, but too rigid and cumbersome a solution to a real problem.
ostree+containers is the realistic solution to that problem, in my opinion. Worse, sometimes, is better.
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.
For example, docs I've referenced in the past are here: https://nixos.org/manual/nixpkgs/stable/#sec-declarative-pac...
It says to run:
nix-env -iA nixpkgs.myPackages
Is this incorrect?- If you want the package just for now and probably not later use `nix-shell -p`
- If you always need the package for a specific project add it to `shell.nix` (`flake.nix`) of that project.
- If you need the package globally use home-manager, nix-darwin, NixOS
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`:
https://github.com/sontek/homies/blob/master/justfile#L14-L2...
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.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.
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.[1]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/ni...
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.
* 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"
Was this straw man mockery really necessary?`
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:
* nix remove foobar.gnu
* nix remove foobar.experimental20220104
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 is a great system, which is why it would be a waste to not invest some thought in it's CLI ergonomics.
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.
git being popular
If its a personal PC I probably also want the package if I ever were to reinstall the PC. => Use NixOS and add it to the configuration.
If its for work I probably want my colleagues to have the package as well => nix-shell.
Once I started using Nix just quickly installing a package felt really hacky to me, just like a dirty workaround.
I just hate when some project's README.md says: "Yeah, just do apt-get install <long list of packages> and you are good to go".
The chance that this works successfully is about 0.
EDIT: typo
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 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.
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 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"...
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.
There's nothing "Haskell-like" in it as far as I can see.
And its real problem, just like with Javascript, is that it suffers from a serious case of roll-your-own-framework syndrome.
If you mean that it doesn't come with the vanilla Linux kernel: just add the nonguix channel and you can install it.
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.
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.
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.
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.
Seems like a fragmented mess to me.
* 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.
search speed:
$ 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?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: 72 flake:nixpkgs#legacyPackages.x86_64-darwin.toilet github:NixOS/nixpkgs/19574af0af3ffaf7c9e359744ed32556f34536bd#legacyPackages.x86_64-darwin.toilet /nix/store/hnvdydra5syylxnxwj2fmn91aqwz26p6-toilet-0.3
73 flake:nixpkgs#legacyPackages.x86_64-darwin.asdf-vm github:NixOS/nixpkgs/b66b39216b1fef2d8c33cc7a5c72d8da80b79970#legacyPackages.x86_ 64-darwin.asdf-vm /nix/store/skk5pfhjnj49gw184jwivd5wakxx5g23-asdf-vm-0.8.1
and for some reason includes a bunch of duplicate packages, so its very confusing: > nix profile list|grep lolcat
22 flake:nixpkgs#legacyPackages.x86_64-darwin.lolcat github:NixOS/nixpkgs/19574af0af3ffaf7c9e359744ed32556f34536bd#legacyPackages.x86_64-darwin.lolcat /nix/store/zxnkjsimmcvv0jnwsy5jxxmjak01k52f-lolcat-100.0.1
46 flake:nixpkgs#legacyPackages.x86_64-darwin.lolcat github:NixOS/nixpkgs/19574af0af3ffaf7c9e359744ed32556f34536bd#legacyPackages.x86_64-darwin.lolcat /nix/store/zxnkjsimmcvv0jnwsy5jxxmjak01k52f-lolcat-100.0.1
71 flake:nixpkgs#legacyPackages.x86_64-darwin.lolcat github:NixOS/nixpkgs/19574af0af3ffaf7c9e359744ed32556f34536bd#legacyPackages.x86_64-darwin.lolcat /nix/store/zxnkjsimmcvv0jnwsy5jxxmjak01k52f-lolcat-100.0.1
Same package name, hash, and version listed 3 times for some reason. I ended up writing an alias that would give me a readable list: > which npl
npl: aliased to nix profile list|awk '{print $2}'|sort|uniq|sed s/flake:nixpkgs#legacyPackages.x86_64-//g|sed s/darwin\.//g
> npl
argocd
asdf-vm
aws-vault
awscli2The 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.
For uninstalling, nix-env doesn't have the -A flag, because it has to operate on the set of installed packages, not Nixpkgs.
They do help you really quick on Matrix though.
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.I don't see why Nix couldn't do the same.
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.
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>
Much quicker than a `brew install` for me.
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.
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.
That's a pretty arrogant statement to make.
I've been using Nix for about 6 years now, and have mostly been using `nix-env -iA`, `nix-env -qaP --description` and `nix-env -e` the whole time.
I'd suggest "declarative package management" as a level-up above this. https://nixos.org/manual/nixpkgs/stable/#sec-declarative-pac...
Nix is just an isolation and sandboxing system for build artefacts.
NixOs can install packages, but it doesn't use nix-env.
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.