The author almost touches on the one more topic that I adore about Nix, but ends up just so missing it: NixOS is absolutely incredible for its ability to be configured through AI tooling. And I don't mean that it's better than other operating systems, I mean that it's the only game in town.
I've been using Nix, both the package manager and the operating system, for years by now. I agree with all of the author's points, it really does deliver, the declarative nature is superb, and there's this constant sense of "hey my stuff is not breaking by itself" when working on it. And it's that declarative, rollback-able, file-based foundation, that makes it the perfect operating system for telling a coding agent to go to town on.
Would I trust Claude to switch my audio stack from Pulseaudio to Pipewire on Ubuntu? Would I trust Codex to install Hyprland on Fedora so I can test out the session? No, in fact I would not trust any agent to do any of those things on any other operating system. But I would trust even goddamn Grok to do that on NixOS, because I can 1) audit the changes before anything is done, and 2) rollback, rollforward, roll-whatever-the-way-I-want-even-on-the-floor-if-I-want-to because IT JUST WORKS.
I concede that this is turning into an unhinged loveletter to Nix, but really, it's the only operating system that lets one operate with this level of confidence. And I know most people don't care about that, since most people don't usually bother to tweak their OSes or switch out window managers, but as someone that does that, I'm never going back to mutable distros. This security is my table-stakes now, and the others aren't willing to pay up.
So for the developers out there on the lookout for their "Year of the Linux Desktop 2026" -distribution, if you're already using AI assistants, give NixOS a try. Maybe start with this in an empty Git repository: "Hey Claude, I wanna try NixOS. Make me a Flake-based starter config using Gnome that I can demo in a virtual machine. If nix isn't yet installed, install it via determinate-systems installer. Include a "vm" target in the flake for building the image, and a small bash script that builds and launches the VM using whatever virtualization is available on my platform."
I switched over to Nix about a year ago. I was a Windows user before that for 30 years and tried Linux a couple of times, but it never stuck. Now I know I will never touch Windows again. With NixOS I've finally found a system that actually works for me — and the full OS configuration is in a repo. My god, I love it so much.
Sometimes I even prefer nix-shells over uv for quick one-off Python scripts.
I cannot sufficiently convey how absolutely barbaric everything else feels in comparison. Not having Nix would be like having to work on code without Git — absolutely unacceptable.
And it really isn't that much work — you do it once. The next time you set up a new system, without Nix, you'll have to do the full configuration all over again.
Have you heard of any good projects for running isolated containers in NixOS that are cheaply derived from your own NixOS config? Because that is what I want. I want a computer where I can basically install every non stock app in its own little world, where it thinks "huh, that is interesting, I seem to be the only app installed on this system".
Basically, I want to be able to run completely unverified code off of the internet on my local machine, and know that the worst thing it can possibly due is trash its own container.
I feel like NixOS, is one path toward getting to that future.
That's hard given most apps have dependencies and often share them.
It will always look like curl is available or bash or something
What's wrong with another user account for such isolation?
They can be isolated to namespaces and cgroups. Docker and Nix are just wrappers around a lot of OS functionality with their own semantics attempting to describe how their abstraction works.
Every OS already ships with tools for control users access to memory, disk, cpu and network.
Nix is just another chef, ansible, cfengine, apt, pacman
Building ones own distro isn't hard anymore. If you want ultimate control have a bot read and build the LFS documentation to your needs.
Nothing more powerful than the raw git log and source. Nix and everything else are layers of indirection we don't need
depends whether you consider rootless Docker "cheap". I tried running ZeroClaw in a Nix-derived Docker (spoiler - it was a bad idea to use ZeroClaw at all since the harness is very buggy) and there is still a potential for container escape zero-days, but that's the best I've found. also, Nix's own containerization is not as hermetic as Docker; they warn about that in docs
If containers are safe enough for ur use case then just use nixos containers they just a few more lines to setup in a regular nixos config
If it isn't enough
there's microvm.nix which is pretty much the same in difficulty /complexity, but runs inside a very slim and lightweight VM with stronger isolation than a container
It doesn't help that there are two NixOS wikis. nixos.wiki and wiki.nixos.org.
wiki.nixos.org claims that nixos.wiki is outdated and unofficial. But both appear to receive updates, and which one wins the SEO game is a coinflip whenever i google a nixos question.
Claude Code has to be actively steered, because while it knows some nixpkgs it surely doesn’t know it enough. E.g. it was absolutely incapable of fixing lldap settings after system upgrade from 25.05 to 25.11. It just prodded around blindly, producing meaningless configs instead learning how the module works.
NixOS docs work for me, but I tend to just go for the nixpkgs source instead. Manuals document options but not how those are actually plumbed through, nor what remains behind the scenes like all systemd unit settings). Claude can do this too, but it goes quite weird roundabout ways with a lot of weird `find /nix/store` and `nix eval`s to get to it, slow and token-hungry (and not always accurate).
This said, Claude is very helpful at checking logs and providing a picture of what’s going on - saves ton of time this way. Plus it can speed up iterating on changes after it’s fed enough knowledge (but don’t expect it to do things right, that’s still on you). It has breadth of it, but not the depth, and that shows at almost any non-trivial task.
You don't have Claude Code git clone nixpkgs and home-manager for local reference?
I feel you on the nix store + nix eval death loop, though it gleans real info. If I weren't on the Claude Max plan I'd probably feel more of the pain. And context is now 1MM tokens which means you're not running out just as it's starting to piece things together, heh.
I do, but it somehow tends to forget how to do things right now and then - despite having notes in memories system - and starts to do them in its own weird ways.
I’m going to experiment with skills next, or maybe make it build a few helper scripts for itself to quickly get some module source from nixpkgs matching flake.lock without having to think of it all. I’m positive about Claude for nix management, merely saying it’s not something that “just works” for now and reading nix code is still on the human part of the tandem.
This said, to be fair - when it gets the approach right, it excels. I was setting up Ente for photos backup and sharing, and it produced a nice overlay with custom patches for my needs from just “figure out why /shared-albums/ redirects wrong and fix”. Found the module, the package, pulled source, analyzed it, proposed a patch (settings weren’t enough), did it - I only had to test, and only because I haven’t provided it with a browser. Felt amazing.
I would have never become a power user of Linux were I used LLM to do the installation of Gentoo once upon a time. :( So do you guys not know much about the distro you are using, or how does this work? I honestly thought your comment was sarcasm, but apparently it is not.
Well, there's layers. When I started using nixOS I read through the guide and wiki but I also used LLM assistance to help create a stable starting point. Then over time I've incrementally added new things to my configuration through a mix of LLM assistance and reading online material.
I think the initial migration towards nixOS is the hardest point, since it requires learning a bunch of new things all at once in order to get the system into a usable state that matches your expectations and preferences. The key benefit of using an LLM is that it makes it really easy to get your system into a useful initial state, and then you can safely learn and experiment incrementally with a mix of tools.
When I started off I didn't understand everything, but at this point I feel I have a very good understanding of everything in my configuration file.
The things to know about the OS are high level things. The rest of its idiosyncrasies you learn just in time through daily exposure like anything else.
Nothing about this changes with Nix nor AI agents.
You can read documentation on an as-needed basis or to your heart's content.
The point is that the majority of the day to day changes I make to my desktop environment aren't so critical that I need to do more than read an AI agent's proposed changes to my config and accept them when they look reasonable.
And I don't think looking up the exact config options to NixOS' networking system does anything to increase my knowledge of the OS. It's just a triviality.
Kind of an interesting thing here where if this is how you view it, it kind shows in itself why you don't actually need it.
Like what is ultimately the difference here for you vs a non-nix user who, as author says, is just dealing with some big ambiguous pile of state? It kind of takes away any upside to using nix, and probably just creates more friction for your AI than just running ubuntu/apt stuff.
The idea is you can keep configuration "in your head" such that you can reason and iterate and fully know what your system is like at any moment. If you actually don't care about that, you aren't getting anything out of it!
The upside of Nix config is that it's the state of my system in a declarative config file.
I have these packages installed and these firewall settings and these users with these permissions and this folder served over Samba and these hotkeys that do these things and these Obsidian vaults synced over SyncThing and these devices in my SyncThing network and Neovim installed with these plugins and ...
This is difference between me and a non-nix user, not whether we can rattle off the exact state of our live system from memory.
The non-nix user has to query live system state, if such query tools even exist for their question, and I get to read a config file. And I get to maintain my system config in git, and I get to deploy my config on all of my machines.
Nix in CI seems like a really excellent match. I don’t care much about the ATproto space - but Tangled has built their CI system on Nix and I find that really compelling. CI Caching is just awful with GitHub actions - so it made me disappointed that Forgejo went that route.
Although I’ve never committed to using nix system-wide, I do enjoy nix-based using https://devenv.sh/ for the very reasons described in the article. It’s much easier than local containers for development.
I've never really understood how version pinning is meant to work with devenv.sh or Nix more generally. If I whack a .tool-versions file in my repo, everyone who works on it can use install the exact same versions of the relevant tools using asdf. That's low tech and imperfect (and certainly not a replacement for all of Nix's features), but it works as far as it goes. None of the examples on the devenv.sh page demonstrate pinning of tools/packages to specific versions.
As best I can tell, Nix enthusiasts think that this is an XY problem and that I shouldn't want to pin individual tools/packages to arbitrary versions. But the thing is that I am a rude barbarian who very much does want to do this, however philosophically misguided it might be.
If you use the flake system (which is technically still experimental, but everyone is already using it anyway), all your flake 'inputs' are automatically pinned in a flake.lock file that can be committed to git for reproducibility. So if you add nixpkgs as a flake input, your nix expressions will always be referring to the same exact package versions until you update the lock file.
The downside is that flake inputs refer to other flakes, not individual packages, so if you update the nixpkgs input it will upgrade all of your packages at once. For some packages such as Python, nixpkgs tracks multiple major versions so you can loosely pin to that version. You can also include nixpkgs as an input multiple times under different git tags/commits and only use that input for some of your packages to effectively pin them. You could keep using one nixpkgs but override the package's source to build it for a specific version/commit, but this setup could break in the future, because the derivation (and therefore build instructions) will keep evolving while your package's version will not. Or, if you really wanted to, you could straight up just copy the derivation from nixpkgs into your local repository and use that instead.
Nix is quite flexible so there's more options than just these, it just takes a little getting used to to find out what's possible. I don't use devenv myself, but some quick googling reveals it works just fine with flakes, so I would try that to see if it suits your needs.
devenv also has tasks/services. For example you need to start redis, then your db, then seed it, and only then start the server. All of that could be aliases, yeah, but if you define them as aliases you can have them all up with `devenv up`. It even supports dependencies between tasks ("only run the db after migrations ran")
I tried installing NixOS a couple of months ago. On first boot, it gave me some kind of USB error, so I said fuck it and went back to CachyOS. Life's too short to reboot every time I want to install something anyway.
I don’t any experience with Nix - but how does it handle software which runs its own updating processes outside the package manager? Specifically thinking about software like Discord, Slack, Docker Desktop, Jetbrains Toolbox, etc.
Is the Nix-ism to just reject using such software?
So Discord, and quite a lot of software like this has actually two layers of updates. There's updates of the web page (which is basically writing a bunch of JS to the home directory) which NixOS does nothing to prevent, and then there's updates of the host program (i.e. Electron) which NixOS disables.
Jetbrains Toolbox is in a sort of different category with tools like Rustup, since it's a package manager of its own. If you manage your IDEs with Toolbox, then your IDE versions are "outside Nix" and not managed by Nix. It's just packaged into its own pretend FHS environment and then doesn't know anything about it being on Nix. That said, updates of Toolbox itself will need to happen through your package manager.
As a last comment, why run Docker Desktop on Linux at all? Like I understand on Windows and Mac - docker is inherently tied to Linux so the Windows/Mac apps abstract away the fact that it's running a VM and doing a bunch of port mapping and filesystem mounting under the hood so you can pretend it's not running on a VM, but on Linux I've always just installed docker straight onto the host.
There’s more to Docker Desktop than just “oh it’s just docker underneath”
1. Unified experience across Windows, Mac, Linux
2. The security posture is much stronger by default. Many people, who would probably be considered the “target audience” for Docker Desktop, don’t bother to make docker-ce rootless, or don’t use podman, so running it in a VM is better, though admittedly often annoying.
3. Not everybody is a CLI warrior. Docker Desktop gives a decent GUI, ways to monitor and control containers visually, and even deploy kubernetes with a single click.
Regarding Docker Desktop on Linux - yeah definitely not strictly necessary. Sometimes it’s just convenient to have a UI instead of fumbling around trying to remember some cli incantation to check for dangling volumes or what-have-you. I think ideally I want to move to Podman anyways - but I’m using pop_os as my dev distro at the moment and am stuck on an older version which doesn’t have their native `podman compose` implementation yet
Except if you go look at nixpkgs half of the technologies grandparent listed are either missing entirely or in a hilariously broken state.
The true answer is that there is just some software that is antithetical to the philosophy of nix. It’s not necessarily nix’s fault that this is the case, but their purism towards resisting opaque binary blobs going into the store reflects on the actual state of what’s available in nix.
You need some impure, nonreproducible way of managing that software. So on nix Darwin I let these opaque binary blobs manage themselves via homebrew and use nix for every other case possible
That's not much different than other distros, because the way auto-update usually works, is it can't use root permissions or the system package manager (in any distro), so it has to install the newer version in $HOME. Once the update is installed, the system package becomes a trampoline to that.
I tried Discord, and this one seems to download some updates on first run, but the version sticks to the one from the system (0.0.127, latest is 0.0.129). So I assume it just doesn't update, or it tries to and fails.
For a personal desktop environment, I just install them normally when there's no up to date nixified option.
For some things I've vibe-coded a nix module on github that uses a scheduled github action to check for underlying app updates and then it generates a new hash and tags a release.
I've done that for claude code and cursor, which is also an opportunity to let me manage their config files from my nix config.
I run NixOS and the number of times ive been able to install something 'normally' (not via nixpkgs/flake) is approximately zero. You cant go to a website and download a binary and just run it. Almost every program references a shared library and wont be able to find it.
Nixpkgs is very complete in my experience, and in the instances where its not, someone usually has made a flake. The only times ive had to custom-make a flake were extremely new programs, or extremely old ones. Often the newer programs had PRs waiting on nixpkgs anyway, and were only a few days away from building properly in nixos-unstable.
They said Nix, so I was thinking about macOS + nix-darwin when I wrote that.
You're right. When I tried using NixOS as my main desktop experience for a few months, I ended up with a custom derivation for various apps I used. That's probably why I made the claude code and cursor modules in the first place.
But I'm also remembering I made my own keepassxc module because keepassxc wants to be able to write to its config file, but I also want to configure it from nix, so I had to make my module use an activation-time script to merge nix config into the keepassxc config file.
I lost interest in NixOS for day to day personal computing, though vibe-coding modules like that wasn't as big of a dealbreaker as there being almost zero laptops that compete with a Macbook.
The other pain is Linux desktop environment stuff in general like dealing with interactions between a Steam game, wayland, and wayland-satellite. Though NixOS helped there since it was easy for an AI agent to investigate the issue, inspect the nix config, and make a targeted, commented patch that shows up in git.
right now I have bought into the Nix koolaid a bit.
I have NixOS Linux machines and then nix-darwin on my Mac.
I use Nix to install Brew and then Brew to manage casks for things like Chrome what I'm sure updates itself. So the "flake.lock" probably isn't super accurate for the apps you described.
> There is also community-maintained support for FreeBSD, though I have not used it personally
I have tried to use the nix package manager on FreeBSD recently. I tried doing some basic things without success. Seems quite broken and unusable, which is a pity because nix on macOS seems decent. FreeBSD is much closer to Linux so there is no technical reason why nix can't be a success on FreeBSD.
nix on FreeBSD just needs more contributors to fix bugs and make popular packages work ! I wonder if it will ever happen. FreeBSD is niche and nix is somewhat niche (still). It's a double niche problem !
After having done the switch to nixOS, I can confidently say that managing a system any other way (like with apt/brew + 20 handwritten bash scripts) really is neanderthal technology and nix is superior in every single way.
It's also great for the AI era, copilot is really good with that stuff.
One thing I love about NixOS is how easy it is to run packages from different sources. For example, I needed an old package that's been removed from nixpkgs several years ago. To run it I just had to add an old release of nixpkgs as input to my flake.nix and add the package from this input. It pulls all its dependencies from that old release and there's zero conflict with the other packages.
nix & nixos are by far the worst way to manage system configuration, except for any other way that's been tried. imagine if there was something with declarative system configuration _not_ written in an insane undebuggable recursive nightmare of a language/stdlib? oh well, I'll keep using it, because what other options are there?
+1, Guix is quite good with some tricks up it's sleeve compared to Nix.
I am not a fan of S-expressions but using scheme is more reasonable than nix+bash to me.
On the negative side, guix can be slow. It is also not a very pragmatic os. NixOS does non-free firmware and drivers without issue. You need to jump through some hoops for this with Guix. This is not an issue if you plan to run guix in a VM though.
I mean it's pretty wild to take s-expressions and not call them extremely terrible to read. The nix language sucks really badly, but I gladly take it over writing S-expressions.
It reads almost the exact same as any functional C-style language. Not to mention that specifically for Guix, you're going to be writing the (name value) form for 99% of it.
That link isn't working for me (something about AI detection), but as a point of accuracy, those aren't derivations, they're simple source files. Derivations are generated out of them.
As for the closing braces, would it be better if you had a newline between each?
I tried NixOS and failed miserably. I've pointed at to the Fedora Atomic distros, which are also immutable, and apparently incomparably easier to setup.
I'm tempted to give it a shot, with the extra bonus that I've never dabbed with a fedora-based distro.
I tried fedora silverblue for a while, but the way it works is that it builds a new root fs image whenever you change the installed packages, this makes system package changes take comparatively long vs a traditional os. They suggest installing most apps via flatpak, which is okay as long as you can deal with flatpak idiosyncrasies.
I also tried fedora coreos for a vm + container host, but found the recommended method to configure the system with ignition files and one shot systemd units to be too involved for making a one off system, and it’s probably better for a cloud deployment with many identical nodes.
This is niche and HN is full of these back and forth comments. One thing which a particular type of crowd will appreciate is being able to apply simple patches to constantly-up-to-date packages.
For an example, I love atuin but it, by default, skips commands starting with space. Currently it's not configurable and while I wait for time to submit a PR or for the issue to be resolved, make a single line `patch` which just removes the part of the `if` statement which checks if it starts with space. So easy, took 5 minutes (also had to comment out 1 test).
And now on home-manager debian or nixos server, I get up to date atuin with that one patch. It downloads rust, etc, compiles, and then that's garbage collected away
Same but with kernel. What lead me to nixos: company gave me a laptop with iGPU that wasn't supported by any released linux kernel. There were patches waiting to be merged, with nixOS making an installer image that supports my machine was simple.
I love Nixos. Having a deterministic system is such a great way to know what your system is capable of. The only thing that bothers me is that when I rebuild my system after updating the lock file, if a package is broken the whole upgrade become impossible.
The idea is so good it’s as close to platonic as it gets. The user experience of writing your own nix expressions is so bad that it makes me angry every time I try. Not only that, but at some point the beginner help (!) meta became »use flakes, don’t do what the existing tutorials tell you, yes flakes are unstable beta and there are no tutorials but use it I beg you«. No, please, let me choose my own way to learn!
I haven’t given it a shot in the LLM age yet though, and trying out NixOS in a VM is not only easy, it is practical – in the sense that when you’re happy, you can simply boot that same config/OS anywhere else by just installing that config. And I’ll never forget that one time where I completely borked my everything in the VM, did a kernel rollback with like 3 command line args and a reboot, and the OS was, well, rolled back. As I said, almost platonic.
What I can recommend is using nix-the-package-manager. Whenever I need the newest version of something, `nix-env -i <whatever>` and it’s there and works. If it doesn’t, roll back. If I need a different version, that’s on nixpkgs as well, with the same negligible amount of friction.
I'm not sure if I live in some kind of parallel world, because I never had any problems grokking Nix or NixOS. I started with this book[0] and haven't ever really been confused.
I haven't tried it in almost a year, but using Claude Code for setting up my nix config back then worked amazingly well. I've only dabbled in NixOS, and I'm very tempted to it for my workstation when I reinstall it in the next month.
Given how much Claude Code + Opus have improved in the last year, I'd give it a fighting chance to make a nice Nix config. I'll probably start setting up a spare laptop to get the base configs dialed in before switching over to it.
Flakes are de facto standard at this point. Expressions are easy once you get used to them - in fact the Nix language grows on many of us, including myself, once you internalize it.
Using AI to generate Nix config is a superpower. Because the entire system is declared in a single set of config, you can basically spell cast any system you want. I one-shotted a Linux distro with custom branding for boot, installation screen, and login screen, and VPN and dev tools installed and configured by default, at a fortune 500 tech company.
Obligatory Guix plug. I've found it way easier to understand, but it has teething issues that NixOS doesn't (latest for me was a few problems with DMs). And according to an acquaintance of mine, it works reasonably well with an LLM.
Yep disk space and learning curve are the two major downsides to Nix. The former has never been a problem for me in practice, just run garbage collection once a month. The latter was a big problem, but is now mitigated for most people by LLMs.
Yes, however the space is not „used up” in a classic sense. It’s a cache, so you can give up some of it and reclaim your space. Fresh after a full cleanup it won’t take much more than a regular distro.
If you don't mind a very limited set of software, the way tinycorelinux is setup can also allow multiple different tcz installed
These two Linux distros essentially allow two different versions of same software/libraries (glibc/python whatever) installed
(Gobolinux explicitly states that whereas I find it to be an unintended but elegant consequence for tinycorelinux but I recommend taking a look at Gobolinux)
The problem I have with nix is that I just don't need another hobby. Keeping everything up to date in an ever changing environment like an os just looks like chore. I install my system and image it every week and keep maybe the initial and a monthly snapshot. Why would nix be better in my case? Maybe I am missing something essential but I also don't bork my system that often tbh.
Nix isn't really much of a hobby. It does require some learning because it's different, and front-loading the work to build your config, but after that it's amazingly reliable and easily extendable. You can keep everything up to date with a single command.
The advantages:
- Declarative code describes your system. Maybe your install + imaging flow is good enough, but there are many reasons why it's technically inferior. There's no need for imaging Nix, because it's always reproducible by default. Rollbacks are rebooting to a previous config, not a timestamped blob of snowflake state.
- It replaces whatever tools and glue you have to build your system. You don't need to worry about bootstrapping tools, or config management tools' version compatibility, or bespoke ordering of imperative steps to build the system. All the management tools are built into the system. Everything "just works" automatically.
- If you manage multiple machines the benefits are compounding.
- There are other interesting bits that are covered in the article, that you get for free just due to the nature of nix. It's good for building, and has no friction to experimenting with specific tools or environments, without polluting your system.
It's a commitment to get past the initial learning and config build, but afterwards it significantly lessens the "hobby" aspects of computer management. There are just entire classes of problems that don't exist for Nix. Either your config works, or it doesn't, and the rollback guarantee is explicit and built-in.
For me, it's the difference between taking your medicine a bit at a time on your own schedule or taking it all at once as an unwelcome surprise. Sure, setting up file system mounts or adding udev entries is easier to do once in Ubuntu than in NixOS, but I only need to do it the one time with NixOS. Thereafter, the config serves as both documentation and backup. For a hobby self hoster like me who occasionally shoots himself in the foot and has to rebuild a system, it is ideal. I don't know if it really saves me time, but I do know it saves my sanity.
I am no nix whiz, but it's the only OS I run outside of containers. Anything I can't easily get with my nix config I shove into a container, run it as a quadlet, and call it good.
Imo it's the opposite. Since the system is defined in config files, an AI agent can look at live system state/errors vs. the config file and do all the work of figuring out the issue.
Also, using higher level modules like home manager makes things more declarative and less fiddly since someone else is maintaining the lower level.
Maybe nix is a downgrade for what you do. But I loved nix so much that I also migrated to nix on macOS (nix-darwin). No more homebrew.
nixos updates tend to be a lot less eventful than others distro, in fact the way it largely prevent system borking when updating, is spiritually freeing.
NixOS kind of extends the idea of reproducible builds. Any snapshot could be a guarantee that things just work. This can also be extended onto the user base - if one user has solved a problem, it should be solved for all of them. So we can jump from guarantee to guarantee here.
My only gripe with NixOS is Nix. I think that this is also the biggest drawback of NixOS. I don't have an alternative; but perhaps it may be better to allow any format to be used, rather than force nix onto everyone.
Another issue is that, for a reason I don't quite understand, a few years ago NixOS' quality appears to have gone down, e. g. nobody cares about documentation anymore. This is probably not a huge obstacle per se, but I did not feel I should invest that much into nix (which I dislike) when the documentation leaves a lot to be desired. Ironically this also means that the whole idea behind NixOS, falls flat, if the documentation is poor. They really should make the same guarantees for their documentation, just as they do for the software ecosystem too.
Nobody cares about documentation anymore though - AI has won. Just try finding high quality documentation via google search; it is slop world now.
I've been using Nix, both the package manager and the operating system, for years by now. I agree with all of the author's points, it really does deliver, the declarative nature is superb, and there's this constant sense of "hey my stuff is not breaking by itself" when working on it. And it's that declarative, rollback-able, file-based foundation, that makes it the perfect operating system for telling a coding agent to go to town on.
Would I trust Claude to switch my audio stack from Pulseaudio to Pipewire on Ubuntu? Would I trust Codex to install Hyprland on Fedora so I can test out the session? No, in fact I would not trust any agent to do any of those things on any other operating system. But I would trust even goddamn Grok to do that on NixOS, because I can 1) audit the changes before anything is done, and 2) rollback, rollforward, roll-whatever-the-way-I-want-even-on-the-floor-if-I-want-to because IT JUST WORKS.
I concede that this is turning into an unhinged loveletter to Nix, but really, it's the only operating system that lets one operate with this level of confidence. And I know most people don't care about that, since most people don't usually bother to tweak their OSes or switch out window managers, but as someone that does that, I'm never going back to mutable distros. This security is my table-stakes now, and the others aren't willing to pay up.
So for the developers out there on the lookout for their "Year of the Linux Desktop 2026" -distribution, if you're already using AI assistants, give NixOS a try. Maybe start with this in an empty Git repository: "Hey Claude, I wanna try NixOS. Make me a Flake-based starter config using Gnome that I can demo in a virtual machine. If nix isn't yet installed, install it via determinate-systems installer. Include a "vm" target in the flake for building the image, and a small bash script that builds and launches the VM using whatever virtualization is available on my platform."
Basically, I want to be able to run completely unverified code off of the internet on my local machine, and know that the worst thing it can possibly due is trash its own container.
I feel like NixOS, is one path toward getting to that future.
It will always look like curl is available or bash or something
What's wrong with another user account for such isolation?
They can be isolated to namespaces and cgroups. Docker and Nix are just wrappers around a lot of OS functionality with their own semantics attempting to describe how their abstraction works.
Every OS already ships with tools for control users access to memory, disk, cpu and network.
Nix is just another chef, ansible, cfengine, apt, pacman
Building ones own distro isn't hard anymore. If you want ultimate control have a bot read and build the LFS documentation to your needs.
Nothing more powerful than the raw git log and source. Nix and everything else are layers of indirection we don't need
If it isn't enough there's microvm.nix which is pretty much the same in difficulty /complexity, but runs inside a very slim and lightweight VM with stronger isolation than a container
Everything seems scattered around a dozen forums, a hundred old blog posts, and a thousand issues of "this work on my machine (3 releases ago)".
wiki.nixos.org claims that nixos.wiki is outdated and unofficial. But both appear to receive updates, and which one wins the SEO game is a coinflip whenever i google a nixos question.
Claude Code has to be actively steered, because while it knows some nixpkgs it surely doesn’t know it enough. E.g. it was absolutely incapable of fixing lldap settings after system upgrade from 25.05 to 25.11. It just prodded around blindly, producing meaningless configs instead learning how the module works.
NixOS docs work for me, but I tend to just go for the nixpkgs source instead. Manuals document options but not how those are actually plumbed through, nor what remains behind the scenes like all systemd unit settings). Claude can do this too, but it goes quite weird roundabout ways with a lot of weird `find /nix/store` and `nix eval`s to get to it, slow and token-hungry (and not always accurate).
This said, Claude is very helpful at checking logs and providing a picture of what’s going on - saves ton of time this way. Plus it can speed up iterating on changes after it’s fed enough knowledge (but don’t expect it to do things right, that’s still on you). It has breadth of it, but not the depth, and that shows at almost any non-trivial task.
I feel you on the nix store + nix eval death loop, though it gleans real info. If I weren't on the Claude Max plan I'd probably feel more of the pain. And context is now 1MM tokens which means you're not running out just as it's starting to piece things together, heh.
I’m going to experiment with skills next, or maybe make it build a few helper scripts for itself to quickly get some module source from nixpkgs matching flake.lock without having to think of it all. I’m positive about Claude for nix management, merely saying it’s not something that “just works” for now and reading nix code is still on the human part of the tandem.
This said, to be fair - when it gets the approach right, it excels. I was setting up Ente for photos backup and sharing, and it produced a nice overlay with custom patches for my needs from just “figure out why /shared-albums/ redirects wrong and fix”. Found the module, the package, pulled source, analyzed it, proposed a patch (settings weren’t enough), did it - I only had to test, and only because I haven’t provided it with a browser. Felt amazing.
I think the initial migration towards nixOS is the hardest point, since it requires learning a bunch of new things all at once in order to get the system into a usable state that matches your expectations and preferences. The key benefit of using an LLM is that it makes it really easy to get your system into a useful initial state, and then you can safely learn and experiment incrementally with a mix of tools.
When I started off I didn't understand everything, but at this point I feel I have a very good understanding of everything in my configuration file.
Unless you're brand new to Linux or computing, it's not a mystery what a given nix config change is ever doing.
You can probably guess what this does:
The things to know about the OS are high level things. The rest of its idiosyncrasies you learn just in time through daily exposure like anything else.I am not brand new - and I don't know what the heck the config is doing.
That is why I rely on documentation.
The "code is self-explanatory" is always an attempt to not have useful documentation and try to rationalise that problem away.
You can read documentation on an as-needed basis or to your heart's content.
The point is that the majority of the day to day changes I make to my desktop environment aren't so critical that I need to do more than read an AI agent's proposed changes to my config and accept them when they look reasonable.
And I don't think looking up the exact config options to NixOS' networking system does anything to increase my knowledge of the OS. It's just a triviality.
Like what is ultimately the difference here for you vs a non-nix user who, as author says, is just dealing with some big ambiguous pile of state? It kind of takes away any upside to using nix, and probably just creates more friction for your AI than just running ubuntu/apt stuff.
The idea is you can keep configuration "in your head" such that you can reason and iterate and fully know what your system is like at any moment. If you actually don't care about that, you aren't getting anything out of it!
I have these packages installed and these firewall settings and these users with these permissions and this folder served over Samba and these hotkeys that do these things and these Obsidian vaults synced over SyncThing and these devices in my SyncThing network and Neovim installed with these plugins and ...
This is difference between me and a non-nix user, not whether we can rattle off the exact state of our live system from memory.
The non-nix user has to query live system state, if such query tools even exist for their question, and I get to read a config file. And I get to maintain my system config in git, and I get to deploy my config on all of my machines.
It's also simple to setup dev environments with nix.
As best I can tell, Nix enthusiasts think that this is an XY problem and that I shouldn't want to pin individual tools/packages to arbitrary versions. But the thing is that I am a rude barbarian who very much does want to do this, however philosophically misguided it might be.
The downside is that flake inputs refer to other flakes, not individual packages, so if you update the nixpkgs input it will upgrade all of your packages at once. For some packages such as Python, nixpkgs tracks multiple major versions so you can loosely pin to that version. You can also include nixpkgs as an input multiple times under different git tags/commits and only use that input for some of your packages to effectively pin them. You could keep using one nixpkgs but override the package's source to build it for a specific version/commit, but this setup could break in the future, because the derivation (and therefore build instructions) will keep evolving while your package's version will not. Or, if you really wanted to, you could straight up just copy the derivation from nixpkgs into your local repository and use that instead.
Nix is quite flexible so there's more options than just these, it just takes a little getting used to to find out what's possible. I don't use devenv myself, but some quick googling reveals it works just fine with flakes, so I would try that to see if it suits your needs.
> How do I set up my development environment using devenv.sh to pin nodejs to 24.14.0?
If I understand your response correctly, I can't do this in any very practical way.
Is the Nix-ism to just reject using such software?
Jetbrains Toolbox is in a sort of different category with tools like Rustup, since it's a package manager of its own. If you manage your IDEs with Toolbox, then your IDE versions are "outside Nix" and not managed by Nix. It's just packaged into its own pretend FHS environment and then doesn't know anything about it being on Nix. That said, updates of Toolbox itself will need to happen through your package manager.
As a last comment, why run Docker Desktop on Linux at all? Like I understand on Windows and Mac - docker is inherently tied to Linux so the Windows/Mac apps abstract away the fact that it's running a VM and doing a bunch of port mapping and filesystem mounting under the hood so you can pretend it's not running on a VM, but on Linux I've always just installed docker straight onto the host.
1. Unified experience across Windows, Mac, Linux
2. The security posture is much stronger by default. Many people, who would probably be considered the “target audience” for Docker Desktop, don’t bother to make docker-ce rootless, or don’t use podman, so running it in a VM is better, though admittedly often annoying.
3. Not everybody is a CLI warrior. Docker Desktop gives a decent GUI, ways to monitor and control containers visually, and even deploy kubernetes with a single click.
Regarding Docker Desktop on Linux - yeah definitely not strictly necessary. Sometimes it’s just convenient to have a UI instead of fumbling around trying to remember some cli incantation to check for dangling volumes or what-have-you. I think ideally I want to move to Podman anyways - but I’m using pop_os as my dev distro at the moment and am stuck on an older version which doesn’t have their native `podman compose` implementation yet
The true answer is that there is just some software that is antithetical to the philosophy of nix. It’s not necessarily nix’s fault that this is the case, but their purism towards resisting opaque binary blobs going into the store reflects on the actual state of what’s available in nix.
You need some impure, nonreproducible way of managing that software. So on nix Darwin I let these opaque binary blobs manage themselves via homebrew and use nix for every other case possible
I tried Discord, and this one seems to download some updates on first run, but the version sticks to the one from the system (0.0.127, latest is 0.0.129). So I assume it just doesn't update, or it tries to and fails.
For some things I've vibe-coded a nix module on github that uses a scheduled github action to check for underlying app updates and then it generates a new hash and tags a release.
I've done that for claude code and cursor, which is also an opportunity to let me manage their config files from my nix config.
Nixpkgs is very complete in my experience, and in the instances where its not, someone usually has made a flake. The only times ive had to custom-make a flake were extremely new programs, or extremely old ones. Often the newer programs had PRs waiting on nixpkgs anyway, and were only a few days away from building properly in nixos-unstable.
You're right. When I tried using NixOS as my main desktop experience for a few months, I ended up with a custom derivation for various apps I used. That's probably why I made the claude code and cursor modules in the first place.
But I'm also remembering I made my own keepassxc module because keepassxc wants to be able to write to its config file, but I also want to configure it from nix, so I had to make my module use an activation-time script to merge nix config into the keepassxc config file.
I lost interest in NixOS for day to day personal computing, though vibe-coding modules like that wasn't as big of a dealbreaker as there being almost zero laptops that compete with a Macbook.
The other pain is Linux desktop environment stuff in general like dealing with interactions between a Steam game, wayland, and wayland-satellite. Though NixOS helped there since it was easy for an AI agent to investigate the issue, inspect the nix config, and make a targeted, commented patch that shows up in git.
And there's also nix alien and similar tools as alternative
But indeed usually you end up using patchelf , tell the inputs of a binary n just make a regular nix package from it
right now I have bought into the Nix koolaid a bit.
I have NixOS Linux machines and then nix-darwin on my Mac.
I use Nix to install Brew and then Brew to manage casks for things like Chrome what I'm sure updates itself. So the "flake.lock" probably isn't super accurate for the apps you described.
> There is also community-maintained support for FreeBSD, though I have not used it personally
I have tried to use the nix package manager on FreeBSD recently. I tried doing some basic things without success. Seems quite broken and unusable, which is a pity because nix on macOS seems decent. FreeBSD is much closer to Linux so there is no technical reason why nix can't be a success on FreeBSD.
nix on FreeBSD just needs more contributors to fix bugs and make popular packages work ! I wonder if it will ever happen. FreeBSD is niche and nix is somewhat niche (still). It's a double niche problem !
It's also great for the AI era, copilot is really good with that stuff.
I am not a fan of S-expressions but using scheme is more reasonable than nix+bash to me.
On the negative side, guix can be slow. It is also not a very pragmatic os. NixOS does non-free firmware and drivers without issue. You need to jump through some hoops for this with Guix. This is not an issue if you plan to run guix in a VM though.
I counted and you regularly see this: "))))))))))" at the end. This is not a language that is optimizing for being written by humans.
As for the closing braces, would it be better if you had a newline between each?
A WIP NixOS config for working with agents:
https://github.com/dangirsh/tsurf
If you’re itching to try Nix, now is the time.
Can't imagine going back to the status quo where my system is the accumulation of terminal commands over time instead of a config file.
I'm tempted to give it a shot, with the extra bonus that I've never dabbed with a fedora-based distro.
I also tried fedora coreos for a vm + container host, but found the recommended method to configure the system with ignition files and one shot systemd units to be too involved for making a one off system, and it’s probably better for a cloud deployment with many identical nodes.
For an example, I love atuin but it, by default, skips commands starting with space. Currently it's not configurable and while I wait for time to submit a PR or for the issue to be resolved, make a single line `patch` which just removes the part of the `if` statement which checks if it starts with space. So easy, took 5 minutes (also had to comment out 1 test).
And now on home-manager debian or nixos server, I get up to date atuin with that one patch. It downloads rust, etc, compiles, and then that's garbage collected away
I haven’t given it a shot in the LLM age yet though, and trying out NixOS in a VM is not only easy, it is practical – in the sense that when you’re happy, you can simply boot that same config/OS anywhere else by just installing that config. And I’ll never forget that one time where I completely borked my everything in the VM, did a kernel rollback with like 3 command line args and a reboot, and the OS was, well, rolled back. As I said, almost platonic.
What I can recommend is using nix-the-package-manager. Whenever I need the newest version of something, `nix-env -i <whatever>` and it’s there and works. If it doesn’t, roll back. If I need a different version, that’s on nixpkgs as well, with the same negligible amount of friction.
[0]: https://nixos-and-flakes.thiscute.world
I haven't tried it in almost a year, but using Claude Code for setting up my nix config back then worked amazingly well. I've only dabbled in NixOS, and I'm very tempted to it for my workstation when I reinstall it in the next month.
Given how much Claude Code + Opus have improved in the last year, I'd give it a fighting chance to make a nice Nix config. I'll probably start setting up a spare laptop to get the base configs dialed in before switching over to it.
Using AI to generate Nix config is a superpower. Because the entire system is declared in a single set of config, you can basically spell cast any system you want. I one-shotted a Linux distro with custom branding for boot, installation screen, and login screen, and VPN and dev tools installed and configured by default, at a fortune 500 tech company.
That is in between "use it for very short period of time" and "use it forever"
If you don't mind a very limited set of software, the way tinycorelinux is setup can also allow multiple different tcz installed
These two Linux distros essentially allow two different versions of same software/libraries (glibc/python whatever) installed
(Gobolinux explicitly states that whereas I find it to be an unintended but elegant consequence for tinycorelinux but I recommend taking a look at Gobolinux)
The advantages:
- Declarative code describes your system. Maybe your install + imaging flow is good enough, but there are many reasons why it's technically inferior. There's no need for imaging Nix, because it's always reproducible by default. Rollbacks are rebooting to a previous config, not a timestamped blob of snowflake state.
- It replaces whatever tools and glue you have to build your system. You don't need to worry about bootstrapping tools, or config management tools' version compatibility, or bespoke ordering of imperative steps to build the system. All the management tools are built into the system. Everything "just works" automatically.
- If you manage multiple machines the benefits are compounding.
- There are other interesting bits that are covered in the article, that you get for free just due to the nature of nix. It's good for building, and has no friction to experimenting with specific tools or environments, without polluting your system.
It's a commitment to get past the initial learning and config build, but afterwards it significantly lessens the "hobby" aspects of computer management. There are just entire classes of problems that don't exist for Nix. Either your config works, or it doesn't, and the rollback guarantee is explicit and built-in.
I am no nix whiz, but it's the only OS I run outside of containers. Anything I can't easily get with my nix config I shove into a container, run it as a quadlet, and call it good.
Also, using higher level modules like home manager makes things more declarative and less fiddly since someone else is maintaining the lower level.
Maybe nix is a downgrade for what you do. But I loved nix so much that I also migrated to nix on macOS (nix-darwin). No more homebrew.
My only gripe with NixOS is Nix. I think that this is also the biggest drawback of NixOS. I don't have an alternative; but perhaps it may be better to allow any format to be used, rather than force nix onto everyone.
Another issue is that, for a reason I don't quite understand, a few years ago NixOS' quality appears to have gone down, e. g. nobody cares about documentation anymore. This is probably not a huge obstacle per se, but I did not feel I should invest that much into nix (which I dislike) when the documentation leaves a lot to be desired. Ironically this also means that the whole idea behind NixOS, falls flat, if the documentation is poor. They really should make the same guarantees for their documentation, just as they do for the software ecosystem too.
Nobody cares about documentation anymore though - AI has won. Just try finding high quality documentation via google search; it is slop world now.