I really want to like Nix. The idea of declaratively defining my entire system sounds great. I can manage it with Git and even have multiple machines all look the same. I can define my partititioning once and magically get a btrfs disk working. Wow!
But I find the language confusing no matter how many times people say it’s easy. I have a lot of experience with other programming languages so maybe it just doesn’t mesh. It also gives terrible error messages that are hard for me to understand. And Nixpkgs is unpredictable for what version I’m going to get. One of the services I installed ended up being a release candidate version which was a surprise. What if I don’t want the latest version of Docker? How do I pin it? Do I have to duplicate part of Nixpkgs? It just feels like a monorepo where everybody has to be on the same versions. Why on earth do the Nix language docs start by introducing math expressions instead of here is a simple self contained thing that installs one program. Here’s how you configure it. Here’s how you expand. Why does the dependency graph seem to pull in so many unnecessary dependencies? For example, I tried to build a minimal Docker image (which Nix looks to be a very good fit for), but I couldn’t figure out how to strip out dependencies that likely were only used during build for a dependency.
I still like the idea and have managed to get my server defined entirely with NixOS which is very cool, but I can’t recommend this to my tech friends because if I’m confused they will be more so.
I have not used Nix, so I may not know what I am talking about.
That said, I have been using Chimera Linux which uses the APK package manager. It works by maintaining a single file in /etc/apk/world that specifies all the packages the user wants on the system. This is used to calculate dependencies and install packages. When you “add” and “del” packages, all it is really doing is adding and removing from this list. If you remove a package, it will remove all the dependencies too unless they appear in the “world” file.
If you do not specify a version number for a package, you get the latest. But you can pin versions of you want.
If you copy the world file from one system to another, you get the same set of installed packages.
So, if I use git to backup my world file, maybe a couple of other entries in /etc, and the dot files in my home directory, I have pretty much everything I need to completely recreate my system.
Is it really worth all the extra complexity of Nix?
The Nix language itself is the hardest part.
Let me disagree there, the language is trivial. It’s just JSON-lookalike with expressions, with a lot of nice touches that make using it much easier than all the alternatives (e.g. sane multi-line string handling, lazy evaluation, default values, powerful key/value sets, etc.). The only real stumbling for me when first encountering it was realizing that functions can only take a single argument (which can be a key/value set) and that functions are literally just
:
(e.g. (a: a + 5) 6 => 11). That’s easily missed if you just look at a file without reading the documentation.The thing that makes it hard is just the complexity of the actual package collection, your configuration contains literally your whole system, and it’s not always obvious where to find the thing you need, since sometimes it’s a plain package, sometimes it is a
services.foobar.enable = true
and sometimes you have to fiddle with override or other package specific things. Knowing that https://search.nixos.org/ exists is half the battle here.There is also the lack of static typing that can lead to rather verbose error messages, but it’s not like many other configuration formats have that either.
I’ve been stuck on Nix for two weeks because I thought it would be a good idea to put a distro I had never used but that wouldn’t break on my backup laptop in case my main one ever broke. I just couldn’t force myself to install debian, not that I have anything against debian, it’s just… kinda boring, while Nix seemed very interesting. IT SEEMED LIKE A GOOD IDEA AT THE TIME I SWEAR.
Guess what happened… I broke Arch. Then I reinstalled and the next day the laptop broke. Then the next day I tried to get my data back and the hard drive broke. So, backup laptop with Nix for two weeks…
- I really really really like the declarative stuff. Installing packages through config files is so nice I’ll never lose track of what I’ve installed ever again 🥰 🥰 🥰 I was already using a git repo for all my config files + GNU Stow to symlink everything to its proper place, so adding the .nix configs to that setup was very easy.
- Having a clean system on rebuild is great. No more clutter left everywhere that I don’t know about, no more half broken stuff left lying around.
But…
- It’s not Arch. Not Nix’s fault, but I kept hearing that it would be “like Arch but declarative”… and it’s really not 😑 Everything seems over-complicated vs as simple as possible.
- I absolutely hate the language.
- What’s with those error messages from hell???
- And speaking of hell, every language that can’t just use indentations like YAML instead of cluttering the code with {} and [] and () should have been relegated to the darkest pit of hell 20 years ago. But points to Nix for being less awful than JSON (the comma on every line but not the last thingy make me want to build a time machine to go murder the grandparents of whoever thought it was a good idea)
- Packages are out of date even in the unstable branch (I know it’s unfair since it’s not trying to be a rolling release… but… but…)
- Where are the source packages? Is that an Arch only thing? I liked having packages that automatically use the latest git commit without needing to manually install from source and manually reinstall each time I want an update like a medieval peasant… 😭
- Nix packages are weird. Even someone who’s terrible at coding like me can read Arch PKGBUILDS… I miss you Arch 😢
- Apps not working because of paths that don’t exist on Nix… what do you mean I need to patch the package myself? 😭 But at least there’s steam-run, great preserver of what’s left of my sanity.
Can’t wrap my head around installing some stuff like VSCode extensions (the advice I got was "don’t bother just do it imperatively…)(Edit: Finally figured it out!!!)- Wiki is often sparse on info and not very helpful if you don’t already know what you are doing (and I clearly don’t 😅)
- Hidden configs. Some stuff works on its own like pipewire even though I haven’t installed or configured it (I went with a minimal install that just gave me a tty then build from there, no DE), and how it’s already configured is not in the default config files. It’s very confusing not knowing why some stuff works and how it’s configured by default.
But it’s kinda growing on me. Like mold. Or cancer. Brain cancer.
Finally managed to enable VSCode extensions without doing it imperatively or using home manager I’m so happy I could cry 😭 😭 😭
It actually wasn’t even that bad, I’m just terrible at understanding documentation I guess
(vscode-with-extensions.override { vscodeExtensions = with vscode-extensions; [ bodil.blueprint-gtk # Gtk Bluprint language support ms-vscode.makefile-tools # Makefile language support bbenoist.nix # Nix language support ms-python.python # Python language support naumovs.color-highlight # Color Highlight ms-azuretools.vscode-docker # Docker donjayamanne.githistory # Git History seatonjiang.gitmoji-vscode # Gitmoji ]; })
Where are the source packages?
It’s reproducible, so random updates are a no-no. You can however just dump the Git URL in your
flake.nix
inputs and then override thesrc
of the package with that. The source gets updated when you donix flake update
next time. Something like this:inputs { ... mypackage_src.url = "github:myorg/mypackage"; mypackage_src.flake = false; ... }
pkgs.mypackage.overrideAttrs (oldAttrs: { src = mypackage_src; version = "nightly-${mypackage_src.shortRev or "src"}"; })
Wow I had no idea you could do that, I’ll try it thanks ! °o°
Nix has more up to date packages than most distros have packages in total. There’s a bot that goes around updating them automatically if they are from github. Maybe there’s an issue with your package?
I think I might have been misusing the term “outdated”, the packages are a few versions behind but they do work. I haven’t run into packages that didn’t work except because of path issues (fixed by using steam-run).
Packages are out of date even in the unstable branch (I know it’s unfair since it’s not trying to be a rolling release… but… but…)
Sure, some packages are outdated. But in terms of percentage of up-to-date packages, it’s (AFAIK) the best out of any distro repo. And that’s perhaps even more impressive of a feat when realizing it also sports the biggest repo. For actual stats: https://repology.org/repositories/statistics/pnewest
Wait how does Nix Unstable have a better score than the AUR? With four times less maintainers? That’s really impressive, especially considering how much more simple Arch packages are to make.
Because you end up feeling unsatisfied with running the thing until you package it. I don’t even understand the Nix language and I still messed around with a couple of packages
I’m sure it’ll get better once I’m more used to it, just venting a bit. Sorry for the rant
I found this very entertaining lol. And it also confirms I made the right choice not using Nix as my daily driver. This sounds like a headache.
Yes it’s a headache if you don’t have a clue what you’re doing and suck at coding like me, but the good parts might make the headache worth it depending on what you want of your distro. A week ago I couldn’t wait to get a new laptop to reinstall Arch, but now I’m actually wondering if I should keep trying Nix… OH GOD HAVE I CAUGHT THE NIX BRAIN CANCER? 😭
I absolutely hate the language
Check out Guix_System_Distribution, it’s just like NixOS but uses a Scheme dialect which is a better language.
While some people love putting Lisp in everything, I really don’t get it. Guix is far uglier than Nix in the language department. Scheme is not a configuration language and thus has none of the nice things that Nix has (multi-line string handling, defaults, lazy evaluation, inline expression, etc.), instead you get multiple levels of macro spaghetti. Furthermore, Guix forces you to turn everything into Scheme, where you can just use plain Bash in your Nix build steps, in Guix that is all Scheme.
I had spent a lot of years with Scheme before starting with Guix and then spend quite a few years with that, but even after all that switching to Nix just felt so much better instantly. Instead of trying to hack a DSL onto of Scheme you just get a language that’s actually build for the task.
If you like parentheses anyway
That is something you can’t quite escape in Nix either. While it doesn’t use parenthesis like a Lisp, the nature of the language and the depths of the sets you are dealing with still makes you end up getting a lot of this at the end of your files:
]; }; }; }; }
Having one
}
too many or too few is a pretty common issue with Nix and feels very similar to Lisp, even when the rest of the language is quite different.
Meanwhile me as a barbarian installing Debian and copying my
~/.bashrc
file (and a few others) if not just remounting/home/
in the new installation every few years.I really feel compelled to share that I actually really fucking love nix. I’ve never felt so confident that my computer would turn on no problem. It was hard and it was rewarding.
Idk I guess I haven’t had it for long but once I got my dotfiles the way I like I just stopped messing with it.
Also nix devshells are pretty dope (◕ᴗ◕✿)
If you download a binary you can just
steam-run
it and it just worksNixOS sounds like ansible in OS form and that has never seemed appealing. Happy to hear why my impression is wrong though!
Personally, the stepping stone I needed to know about is Nix Home-Manager, which basically allows you to manage your dotfiles independent of the distro. From what I understand, if I do switch to NixOS, I’ll continue using this code with just some minor tweaks.
But yeah, I agree with the verdict in the post. I like it a lot, but I would not have made it past the initial learning curve, if I didn’t happen to be a software engineer. Sysadmins will probably be able to figure out how to put it to use, too. But it’s just not for non-technical Linux users.
Untrue. I came from windows, to Linux mint, then now I daily nix. I’m an average person who prefers to be terminal hands off. I did a full custom install from my mint setup to nix, apps, luks, the entire swap and booted as if I never left basically. I faltered a few times and had to select previous generations in my boot menu but honestly it’d because somehow I fucked up my UUIDs. The learning curve is there but let me assure you it’s minimal in terms of linux, and it’s dead stable because nothing changes without you doing it. In 1000 years it should still be running Unadultered.