Three Years of Nix and NixOS: The Good, the Bad, and the Ugly
Three Years of Nix and NixOS: The Good, the Bad, and the Ugly

Three Years of Nix and NixOS: The Good, the Bad, and the Ugly

Three Years of Nix and NixOS: The Good, the Bad, and the Ugly
Three Years of Nix and NixOS: The Good, the Bad, and the Ugly
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...
But...
But it's kinda growing on me. Like mold. Or cancer. Brain cancer.
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).
I wonder what your thoughts on guix would be, especially considering your thoughts on the language
Succinctly : "OH GOD MY EEEEEYES"
I'm not a fan of nested parenthesis... but aside from that I don't know much about the language, is it more convenient? Does it also suffer from the error messages from hell problem?
I'm just seeing your comment after I recommended Guix, that I could read and understand Guile Scheme is what made me hop away from NixOS, the nixlang is an ungrokable mess
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
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 the src
of the package with that. The source gets updated when you do nix 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°
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
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)
Yeah, fuck that guy!
There's one evil genius responsible for both JSON and JavaScript? °o°
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 ]; })
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.
One of my machines i've been just upgrading in place since debian 8. No need for new installation
Debian isn't barbaric at all.
Skipped to the "ugly" part of the article and I kind of agree with the language being hard?
I think a bigger problem is that it's hard to find "best practices" because information is just scattered everywhere and search engines are terrible.
Like, the language itself is fairly simple and the tutorial is good. But it's a struggle when it comes to doing things like "how do I change the source of a package", "how do I compose two modules together" and "how do I add a repo to a flake so it's visible in my config". Most of this information comes from random discourse threads where the responder assumes you have a working knowledge of the part of the codebase they're taking about.
I always aim at packages and issued inside my nix config cuts all this hassle out atleast for me.. Ive got everything pretty meticulously commented and in order of boot process and in general running step by step order. I'm pretty sure I dumb monkey could figure out how it runs. I came from windows then mint then nix. To give you an idea of my PC knowledge. I think the whole point if nix is to keep the system contained and not scattered. I see many posters mentioning system scatter on nix as an issue and I have no idea how theu managed to complicate one if the simplest systems I've ever used as far as clean, tidy, goes.
Agreed with the article. There’s lots to dislike about Nix, but even with those downsides, NixOS is still better than any OS I’ve tried. Install an update and it’s borked? No worries. New PC and you want everything set up just like your old one? Copy one file over and it’s set up for you.
Copy one file over and it’s set up for you.
So, I've only played around with NixOS on a Raspberry Pi, but... Don't people usually split their config up in multiple files, and then store than in a Git repository?
The process then still is: check out that Git repository, except there's another step: copy over your private key so that you can decrypt your secrets.
Is that correct? Or did I make things needlessly complex for myself?
The process then still is: check out that Git repository, except there’s another step: copy over your private key so that you can decrypt your secrets.
I store my secrets in a separate private git repo and automatically decrypt them with my hardware key (https://github.com/balsoft/nixos-config/blob/master/modules/secrets.nix) so for me it's literally just plug in my yubikey and nixos-install github:balsoft/nixos-config#hostname
Way over complex lol. I don't copy anything to online source for better or worse. I auto script backups. The only backups you'll ever need are nix config. Nothing else aside from your home folder obviously. With those two you can boot on any machine, anytime, as if you never left. I am not shilling. It's been dead stable so far, aside from tweaks I done to break my own builds testing.
I don’t have any secrets in my config or a private key or anything and I’m currently running 4 servers from the same config (it used to be 8 or even more machines at some point even, including desktops).
But yes, it’s a multi-file config, it would be absolutely crazy to not split it up with how large it is.
Unsure about dislikes. You have any desktop spin as you want, complete freedom, immutable, a single small file governs your entire system. I daily Nix currently and I haven't found an easier distro. I'm not super advanced and I did a full custom build, luks, tweaks, full app installs from scratch. Booted up as if I never left my old PC. Nix is the shit. Most everyone's concerns are overblown. Most haven't used it beyond a simple test run or few. The slight learning curve of your config syntax and that's it. I came from mint then from windows. Newcomers you can do it too!!
Install an update and it’s borked? No worries
OpenSUSE also does this.
New PC and you want everything set up just like your old one?
Install scripts? Of course the individual apps definitions still need to be set up again, but I'd imagine it's the same for 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.
There are a few gnarly things about Nix, even for someone who's familiar with Haskell (the most similar language to Nix that's even close to mainstream).
builtins
) is extremely sparse. You basically have to depend on at least nixpkgs-lib
if you want to get any real work done._type
field or some such.${
or ''
? I have to look them up every time.Using a language server like nixd also helps a lot with auto completing packages and options in your config.
Apparently people are also working on the nickel configuration language to address some of the nix limitations and difficulties.
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 (◕ᴗ◕✿)
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.
NixOS sounds like ansible in OS form and that has never seemed appealing. Happy to hear why my impression is wrong though!
Think about it like this:
Thanks for explaining
Ansible is idempotent with a lot of intent. NixOS is idempotent.
This is a well-written post. I agree that “friction” involved with small changes and incompatibility with some Linux binaries are significant downsides. I think NixOS makes a lot of sense for development environments, but it’s not my preference for a personal device
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.
It's missing the fact that the nix store can be huge, even if garbage collected regularly. This prevents me from using nix on my Ubuntu laptop with limited HDD space.
For rollbacks, I've been using Timeshift in Mint, and it has worked brilliantly.
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?
I wonder why nobody has created a simple gui for Nixconfig.
Something like this is really hard to make a gui for. I suppose a GUI would only be useful for discovering config values?
Either way, a gui would likely look like YAST on OpenSuse.
Someone has done just that: https://github.com/snowfallorg/nixos-conf-editor It is part of https://snowflakeos.org/, though I don't know about its developments atm.
It's less simple than text because it actually takes more space to view the same amount of configs.
I like the idea of nixos, but I feel like it makes a bunch of daily sacrifices in order to optimize a task I do once every few years? I hardly ever get a new computer, but I install/uninstall/update/tweak packages on my system all the time. With a dotfile manager and snapshots, I get most of the benefit without any of the drawbacks.
For DevOps, it provides consistency for every CI run and production deployment, especially when a whole system needs to be shipped.
I'm always on the go, swapping PCs, travelling for medical reasons. Buy, sell, trade hardware. Nix allows me to boot into my system as if I never left with a simple hardware config update script. Rock solid consistency.
This is a good example of what people consistently overlook/misunderstand, when it comes to Nix.
Obviously you can remount a /home, or just pull the dotfiles from a personal repo, but the strength of Nix is also in that I can re-create my entire config exactly how it is defined. If i were to setup a machine completely from scratch, with a mature enough config, it will get me from 0 to my exact desktop completely unattended.
But there are also many more advantages to it, at least in my eyes. Let's take trying/tweaking new packages as an example. Yesterday I pulled an old repo for an Outer Wilds mod. The thing needs a dev environment, and a mod manager for the actual game. A
nix shell
got me both, I finished my work, and when I exit out of fish, both are gone, just as I wanted them to be.Another good example would be partial os updates. I've used Arch for almost 9 years before switching to Nix, and pretty much a top3 Arch rule is not doing partial updates, or partial rollbacks. In case of a breakage, I would have to manually redownload an older version of a tarball,
pacman -U
the package, and then hope i'm not cooked. In the case of gcc incompatibilities, it can quickly become a massive pain in the ass. My nix flake would never experience this problem, because I already have two different scenarios available - either i build based on an older lockfile from my git repo, or I create an overlay for a specific input I need, so that it still pulls what it needs, and doesn't interfere with the rest of my systemI feel like setting up a new machine is just the easiest to explain.
Personally, I find dotfiles messy, as you often just want to change one or two settings, but you always carry along the whole file with all kinds of irrelevant other settings. This also makes it impractical to diff two versions of those dotfiles, especially when programs write semi-permanent settings into there.
I guess, your mileage will vary depending on what programs or desktop environment you use.
For example, I love KDE, but they really don't do a good job keeping the config files clean. Nix Plasma-Manager generally fixes that, and for example allows defining the contents of the panel in a readable form.
I think you over complicating your view here. I daily nix. Your not carrying a bunch if dot files. You have one. A single nix. Config. That's it. It's not big, long, messy, what so ever. I have mine commented by section from boot order to auto updates and backups. Your talking about 150 lines of extremely short and almost self explanatory code. I came from mint having never used nix. I figured it out doing a custom luks install and the whole custom build from scratch in no time.
Your diff issue is overblown. The edits you make are small and you cannot get lost in multiple configs unless your doing entire system writes which you would never do. I use a dead light weight diff GUI or terminal. This has to be one if the cleanest, maintenance free distros I have ever used.
It doesn't seem you have truly driven Nix with this take. No program writes directly to your config, even if there was say your temp scenario you reboot and temps would wipe away like you never did them unless you rebuild nix config. Most of your concerns would fall away once you really drove nix to see how it functions.
It also is an option to ensure everyone has the same dev environment.
Meh. So is docker.
Loved nixOS but couldn't install PIA VPN gui and disliked the workarounds. Also doing .net dev was more awkward than I liked so went back to Arch and wrote some scripts to install all the packages I want instead. Love the idea of nixOS though.
Package your own if you need it
I've used nixos exclusively lately. It's been awesome. No system scatter, clutter. It'd immutable. There's very slight driver hassle (you don't have GUI for drivers so a simple terminal command fetches everything you need.) in cinnamon. I came from mint. I have all basic commands in executable files on desktop for ease of hassle. It's not about rebuilding the system. Its about being hands off. Next to zero maintenance because not much in your system gets altered. I went for a full custom install from terminal. The only thing I personally miss being GUI is a firewall like UFW or GUFW.
Overall its more rock solid and workable than likely every distro I have ever tried. The feature set is nice, easy rollbacks, fucking cake backups. All you have to know is your entire system lives on one small editable file called nix. Configuration. Keep it in a micro SD or USB or any backup and it's as if you never left. Any changes you want you simply tweak in the config then reboot. If it breaks then select your previous gen number on boot and your exactly where you was before.
I diff my edits and keep copies, run auto backups, and more. It's so hands off that I haven't found a better replacement yet. My single biggest concern is long-term viability in the project.
You only have one machine? I benefit from sharing configs between the laptop and the desktop. They are not the same, but I can easily copy paste a complex service I defined in my desktop to do the same thing on my laptop
I have a desktop, laptop, and a few VMs and servery things. Dotfile manager (yadm, which is a git wrapper) to sync personal settings, everything else I just do manually. The system-level configs are either different enough that standardizing them isn’t very helpful, or no more complicated than installing packages and activating services.