When the parts were almost in, I had decided to really start digging into NixOS. Friends on IRC and Discord had been trying to get me to use it for years, and I was really impressed with a simple setup that I had in a virtual machine. So I decided to jump head-first down that rabbit hole, and I’m honestly really glad I did.
NixOS is built on a more functional approach to package management called Nix. Parts of the configuration can be easily broken off into modules that can be reused across machines in a deployment. If Ansible or other tools like it let you customize an existing Linux distribution to meet your needs, NixOS allows you to craft your own Linux distribution around your needs.
Unfortunately, the Nix and NixOS documentation is a bit more dense than most other Linux programs/distributions are, and it’s a bit easy to get lost in it. I’m going to attempt to explain a lot of the guiding principles behind Nix and NixOS and how they fit into how I use NixOS on my desktop.
I’m hearing more and more people talk about NixOS lately, and I’ve been wondering why. This article is an excellent overview into this unusual Linux distribution.
White on black monospace text with markdown formatting? I would read this article even if it didn’t interest me!
Superficial aesthetics aside, thanks for the article, I’ve been keeping an eye on NixOS for a while now.
I use NixOS as my daily driver. Basically, I mosh into my Nix box and do all my development there from my Mac, which I keep as a thin client. It’s an AMAZING way to manage a system, and once you go declarative/functional, you’ll never want to go back.
The Achilles heel of the entire Nix ecosystem, however, is documentation. It’s really, really bad. The community is phenomenal but they have limited time to spend on non-development tasks and I don’t think there are very many corporate sponsors. Many (if not most) of them also don’t seem to be native English speakers, which doesn’t help the matter. Finally, and this may be my bias, but you get the impression that the whole concept is so esoteric and difficult to communicate to non-technical people that the project tends to attract a certain type of developer, the kind that isn’t really interested in things like documentation, organizational policies, backward compatibility, etc.
I’ll give you a small example. NixOS’ packages contain NPM packages. The officially sanctioned way of adding or updating a new package is to run a script inside the packages master repo that will not only add or update your package but also update every single NPM package tracked by the repo–literally thousands of packages. There is no official way at the moment of simply adding or updating just your NPM package. When I asked about this peculiar behavior, the response was that it’s not a bug, it’s a feature, because this way no NPM packages get stale and besides, if you want stability you can always either override the package recipe manually or pin the entire package set to a specific Git revision (which, by the way, isn’t a properly documented thing).
Like…are you serious? The whole point of having package maintainers is so that the packages don’t get stale. It is a human process for a very good reason. This is something that can be assisted by scripts but certainly shouldn’t be completely scripted by design. Yes, they are low on resources, but how can you say that is an intentional decision to force thousands of packages to update just to modify one? When I brought this up, it seemed to bring on a collective shrug from those I reached out to.
I also don’t totally understand why they continue to use the obscure Nix language, which was part of Dostra’s Ph.D. thesis. Surely they should move on to Haskell or something with more popularity by this point.
Yeah, I love NixOS to bits and will continue to use and contribute, but there’s no way that they’ll get mass adoption even amongst highly technical Linux power users unless they change some of their views to be less hacker-y and more focused on boring, basic stuff like maintaining version and API stability inside of releases (let alone between them).
I feel like you wrote the reply I wrote almost exactly with a few minor differences. The similarity is almost creepy.
I’d love to see Haskell in use instead of Nix, though perhaps Dhall would make more sense in this context. Not widely used, but doesn’t feel quite as obscure, and there are some Dhall Nix conversion utilities
That’s basically how NPM works. Nix is right to not introduce silent failure points between upstream packages. Stop using JavaScript if you don’t like it.
tidux,
I’m not at all familiar with this package management system, can you explain what it’s doing? The way crazed-glue refers to it makes it sound like the implementation is less efficient than it should be, is that possible?
I’m confused by this because he didn’t mention javascript, and the Nix language isn’t quite javascript. I assume that’s what you meant?
https://nixos.wiki/wiki/Nix_Expression_Language
Personally I prefer strongly typed languages better than javascript in order to reduce bugs, but depending on the environment you are working in you may face additional costs/barriers for not going with the flow.
I think that tidux was suggesting that I shouldn’t use the JS ecosystem with Nixpkgs, i.e. NPM, if I don’t like the JS ecosystem’s norms because Nix is merely replicating the JS ecosystem’s norms, that’s what I understood. But Nixpkgs/NixOS isn’t replicating NPM’s behavior, if anything it’s deviating (see my other reply).
How is that how NPM works? Last time I uploaded a package to NPM, it didn’t cause NPM to update the versions of every other package hosted on NPM–that would be madness (as a thought exercise; it would be impossible in practice since there’s no “upstream” for NPM the way that NPM is upstream for Nixpkgs’ JS packages). Yet that’s essentially what Nixpkgs’ blessed mechanism for updating or adding a new NPM package to the repo does, it causes every other NPM package exposed through Nixpkgs to update.
I would argue this behavior is contrary to the expectations of most audiences when it comes to package management. If you’re a developer using NPM packages, you expect the versions to be pinned to a specific version or range. If you’re a non-technical user, you expect the versions to be curated so that they work, even if they’re not the latest. If you’re a program depending on other packages in a collection, you expect your dependencies to not change from under you. The only use case I can think of is if you’re the most casual user of a package that has no dependencies and you really don’t care whether it breaks or completely changes its behavior from time to time.
Besides, If the goal is truly to keep all the packages constantly updated without any human oversight and *only* offer one version (i.e., the latest version) of the package, which is what people claimed when I asked, then there are better ways to do this than the ad-hoc approach of updating everything whenever a maintainer decides to update a package.
I think the real reason why the team has “chosen” this approach is because it’s the easiest path, and it’s now been rationalized as an intentional design decision. I don’t have any problem with going with the easiest thing, especially when resources are low, but the rationalization doesn’t make sense to me. The very least they could do is document their reasoning.