It's not for everyone.
Specifically, because Nix's 'costs' are upfront (for likely future benefit), nix isn't well suited to just-get-it-done pragmatic attitudes. -- e.g. if you'd prefer to just launch VMs from the web console, over using a tool like Terraform, then Nix isn't going to be for you.
Nix isn't too difficult to use. I'd say it's 95% wonderful, 5% huge pain to deal with. (Writing new nix code can be very hard).
As to why it's worth learning:
> What makes it stand out?
Nix provides very expressive control over packages of software.
e.g. With nix, it's easy to have multiple versions of the same software running on the same system. Whereas, with package managers, if you upgrade, you aren't able to easily also keep the old version around.
Some of the use cases Nix allows are pretty neat:
- You can declare a set of development tools to be made available. So, when you load up the project, you don't have to copy-paste "apt-get install...". This is especially useful for side projects you might not touch all the time.
- There's a "nix run" command, which can act a bit like "docker, without containers": it will download the package, and run it on the host.
- NixOS makes use of Nix so that the system configuration is all declared starting from a single file. Rolling back changes to system configuration is easy, in case you accidentally misconfigure the system. -- This can be used to build container images or VM images.
- Nix can be used to declare what packages you want installed for your user, and declare the configurations for these files. This allows ensuring you have a familiar setup quickly on a new computer.
All sorts of programming involves dealing with packages.
To clarify a bit on the details: nix declares packages in a pure way, using all of its inputs (source code, compiler, library dependencies; which are themselves declared with nix), and builds these in an isolated/non-global directories. Packages are 'installed' by symlinking to where the package is placed.
One difference: On Nix's homepage (https://nixos.org), the first word which stands out is "reproducible". -- If I search the read the docs for "reproducible", the word shows up once. https://modules.readthedocs.io/en/latest/index.html
Not sure if there's anything recent, but links from this may be useful: https://github.com/freuk/awesome-nix-hpc
https://hpc.guix.info/blog/2022/05/back-to-the-future-module...
*Although `nix-shell` in newer unified `nix` command has been broken to few subcommands. Can find more info at https://blog.ysndr.de/posts/guides/2021-12-01-nix-shells/ if interested.
Depends on what exactly you're trying to do. I discovered nix years ago when I was trying to install a newer version of Java than was available in the Ubuntu repos, and the "nix-env" method (just using nix as a package manager without the declarative config) was the only thing that just worked with no hassle.
Today, some Steam Deck users are using Nix to supplement their console's desktop experience with familiar tools without the overhead of Flatpak or the risk of modifying the base system (in which case modifications are nuked on SteamOS updates anyhow).
Determinate Systems did some work to enable and document that, and one YouTuber recently posted an intro/walkthrough of their docs as well.
Video: https://m.youtube.com/watch?v=ttOs5iWgNzk
Secondary documentation (YouTuber's blog): https://christitus.com/steamdeck-as-a-desktop/
Primary documentation by Determinate Systems: https://determinate.systems/posts/nix-on-the-steam-deck
(Some of the work relevant here was done by folks outside of Determinate Systems as well. The installer workgroup is not exclusively DSers.)
Sometimes it just fits a use case so much better than alternatives that it's an obvious choice.
I'm just starting a serious learning journey with Nix after flirting with the idea for a few years. Mostly because I find myself endlessly working on tooling to support the projects I work on that Nix already does extremely well.
The feature I am most sold on is the ability to invoke clean complex development environments, that bring themselves to existence automatically as I traverse directories. If you work in code or in DevOps, Nix is totally worth a look.
I'm a big believer in Nix's high-level approach to declarative systems, but the whole UX of Nix is so poor that foregoing declarative systems altogether is quite a lot less painful than using Nix in my experience. I'm rooting for it, but it really feels like Nix needs a product manager or something (no disrespect to the maintainers; these are difficult problems and I'm sure I wouldn't do a very good job). New users should beware.
In my experience:
With fewer nix users on macOS, it's more likely you'll run into software which isn't in the binary cache, & so will compile from source. (brew also does this).
With fewer nix users on macOS, it's may take longer for packages broken on macOS to be fixed.
It's a bit more of a hurdle to use .app programs out-of-the-box compared to brew, due to the symlinking.
I just use brew for .apps (and only for .apps) when I'm on macOS.
This isn't necessarily true, unless the package happened to fail to build on Hydra, or it just hasn't been built yet. (Every package is built for every platform that has builders in Hydra, it's not a matter of maintenance unless it just doesn't build.)
Does brew do this differently? I thought they also automatically compile every package.
Worth reading for Nix people and prospective Nix users alike, imo.
IMHO, it seems like there should be a UX working group that starts with broad scenarios and personas and develops a vision of what tooling should look like and works from there, rather than haphazard, incremental improvements on the current state of Nix tooling/workflows/etc. It could be interesting to look at how the Rust project makes big ambitious changes (they seem to do a really good job from my vantage point). Again, this is my view from afar as someone who has never run a big open source project and knows relatively little about package management (though thanks to Nix, much more than I ever wanted to know!).
and that will stay this way if Apple continues to make major and breaking changes with every update and changing MacOS more and more away from a BSD system and locking it further down.
The Nix community is doing exciting work but in the long run I wouldn’t be surprised to see another project take its place in the mainstream once the ideas have matured. The current space has much of the same chaos as projects like Oh My Zsh or Spacemacs and needs to be treated more like an active hobby.
All that considered, the core paradigm is a breath of fresh air and I can’t imagine going back to a mutable system.
If your work tends to be more isolated and self contained on stable unchanging mainline or mainstream versions of any dependencies you have. Then it’s not worth your time and you won’t appreciate or understand it’s value.
I've had my system get "borked" on updates in the past, and Nix lets me revert very very easily. Also upgrading libraries for one App can easily be isolated from breaking other applications and etc.
It's got tons of flaws (to me), but the core idea to me is a foundation for a super stable system. I both love Nix and hate it. It's so good that myself, a large critic of the OS, still uses it.
Granted Btrfs sounds great though, i've not used that. It would certainly help.
I just take occasional snapshots before I do things that I'm concerned may be catastrophic. But it definitely won't catch everything. It helps that I run Arch, and I update packages once a day, which only leaves me with under 40 (small) packages usually. So a quick cursory glance at which ones are updating usually tells me what to be cautious of. Display driver update, kernel update, etc.
If I'm not sure what went wrong, but I at least have a working snapshot, then I can get done what I need to get done, and then go back to troubleshooting. Rather than just having a broken system regardless.
One potential answer to this is, "imagine building and running software with lockfiles for _literally everything_". I'm not just talking about _versions_ of dependencies or shared libraries - which nix does - but also things like:
- Locking the current point in time (nix resets the build sandbox to the unix epoch)
- Locking out network conditions (all build dependencies need to be fetched and therefore expressed as part of the instructions and not left to "at some point during the build")
- Locking out access to any system state (again, builds occur in a sandbox populated only with what you indicate within the build instructions)
That's what's behind the marketing for reproducability and repeatability. If you lift those principles into new and interesting applications, the various other uses for nix fall out of it:
- NixOS takes the principle of those nix builds and applies to it building not just packages, but the system entirely, like the files it places in /etc or the running kernel.
- Projects like devenv[1] or flake devShells in general re-use the portability of a fully-defined nix package to ship hard-to-break executables into share-able devshells so your peers can work with the bit-for-bit same version of Terraform or python (without worrying about what version of /lib/libssl.so they may have)
- Since nix "owns" the _entirety_ of the inputs and outputs to a piece of built software, shaping it into different artifacts becomes trivial. For example, as long as you're able to build a rust project with nix, nix easily lets you kick out a minimal OCI container (without needing to write a `Dockerfile`), or produce a tiny qemu clone of your system (or any system) by feeding your NixOS configuration into a function that produces images instead of configuring your running system.
Hopefully that's helpful, sorry if it isn't - but nix is sort of alien software, and nix people are still learning how to best share its potential with others!
edit: list formatting
[1]: https://devenv.sh/
Potentially it can save you time in the future. Moving to another hardware is a breath.
You can use derivations as (/ to represent) - packages - generated configuration files / settings - containers - whole OS images ... e.g. I'm building raspi SD card images using Nix.
For some people this is good because future shock has made relying on system libaries to run things very troublesome. So troublesome it compares to the above.
I said "a lot more to it" as well...