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
Other than that I very much agree, patching stuff is wonderful in nix-land! Especially when things in nixpkgs-unstable break.
{ pkgs }:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
# build tools
cmake
ninja
gnumake
pkg-config
];
buildInputs = with pkgs; [
# java
jdk8
# compilers
gcc
clang
llvmPackages.libcxx
# libraries
capstone
icu
openssl_3
libusb1
libftdi
zlib
# scripting
(python3.withPackages (ps: with ps; [
requests
pyelftools
]))
];
# capstone headers are in include/capstone/ but blutter expects include/
shellHook = ''
export CPATH="${pkgs.capstone}/include/capstone:$CPATH"
export CPLUS_INCLUDE_PATH="${pkgs.capstone}/include/capstone:$CPLUS_INCLUDE_PATH"
'';
}Btw, I say this as a huge fan and heavy user of both Nix and NixOS.
Modules let you express the system in smaller, composable, reusable parts rather than express everything in one big file. (There are other popular tools which support modules: NixOS, home-manager, flake-parts).
That devenv also provides "batteries included" modules for popular languages (including linters, LSPs) is also a benefit.
devenv does not do any user-level change (you will not be able to make it configure your WM), but works at the directory level.
For instance I'm currently working on a Rust + C++ project, and my devenv, whenever I enter this project folder: make CMake/g++/cargo/cbindgen available, enable a couple scripts to longer CMake invokations, set-up everything required for C++ and Rust LSPs, and create a couple git hooks to validate formatting etc.
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.
languages.javascript.enable = true
languages.javascript.package = pkgs.nodejs_24 ~/repos/nixpkgs$ git log --grep='nodejs.* 24.14.0' -1 origin/master
commit 9c0e2056b3c16190aafe67e4d29e530fc1f8c7c7
Merge: d3a4e93b79c9 0873aea2d0da
Date: Tue Feb 24 16:53:40 2026 +0000
nodejs_24: 24.13.1 -> 24.14.0 (#493691)
~/repos/nixpkgs$ nix eval nixpkgs/9c0e2056b3c16190aafe67e4d29e530fc1f8c7c7#nodejs_24.version
"24.14.0"
~/repos/nixpkgs$In general though when working on a team, you dont really care about the _exact semver version_, you care about the major and handle version bumps by bumping the pin of nix packages.
The way to do it is to find the `nixpkgs` version which contains the version of the tool you care about. There's a web site[1] that makes this pretty easy, and it's of course also doable by looking at the Git history for the program's derivation.
Then you create a named input using that nixpkgs version: either add it as a channel, import it with fetchTarball in a derivation, or add it as an input in your flake, depending on what you're doing. Then you use that named nixpkgs (or other input in the flake case) for that version of the package.
Edit: One issue with depending on things like git tags or semver versions is that sometimes people re-use versions or edit tags. Using the actual git commit hashes of the package's derivation avoids this potential ambiguity. This is why we can't have nice things.
Is the Nix-ism to just reject using such software?
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
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.
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.
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.
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
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.
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
Personally, I don’t see the need for this with NixOS. Setting aside the fact that Omarchy is way too opinionated (Basecamp installed by default?), NixOS is already quite composable, so you can easily build a well-formed experience out of isolated NixOS modules.
* IMO Omarchy doesn’t make sense anyway, far too much opinion and too little utility. It’s not a distro it’s some guy’s overly promoted pile of crufty scripts and dotfiles.
My entire config is almost "omarchy", at least visually with hyprland and some other packages.
I had issues when giving boot partition only 512mb, so I'd recommend going with 1G.
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.
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.
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.
It's also simple to setup dev environments with nix.
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.
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.
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.
A WIP NixOS config for working with agents:
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.
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)".
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.
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:
networking.firewall.allowedTCPPorts = [ 8080, 9000 ];
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.
NixOS does you one thing better by giving you the option to configure things without caring about the underlying implementation, like whether the firewall uses iptables or nftables or something else.
Fails to parse is what it does...
Are we really living in times where people can't write a single (syntactically) well-formed line of code in a programming language they use?
I understand this doesn't really matter when just using NixOS Slop Edition™ but man I hate it.
Jeez, tough crowd.
Though it also kinda represents this pride over triviality that some people latch on to in the AI world which is odd since it's also only a mistake a human would make. Had I run my hand-written comment through a proofreading clanker, I would have spared you the negative emotional reaction.
In the pre-AI world, you would have probably not been so harsh since it's understandable that someone make that mistake with such an idiosyncratic language like nix that almost nobody writes full-time. Yet in the AI world, you demand more from humans.
Something interesting, there.
People are being more demanding of humans because humans are taking knowledge and learning for granted. All this abstraction has a cost, and the cost is you.
Despite many years of experience, I still sometimes get this wrong in Python or its equivalent in the other languages I regularly switch between:
from math import sqrt as s
import sqrt as s from math
import sqrt from sqrt as s
The difference here is that, because I admitted to using AI, I don't get the grace of making the most trivial mistake in a forum comment.And suddenly we pretend that had I just written it by hand a few more times, I would never err again in forum comments, despite making similar errors this week in languages I've used to write millions of lines of code across decades.
That's true, and I should've been less rude in my previous comment. Sorry.
(Though note `nix eval` would've sufficed, no need for the probabilistic kind of clanker)
> Yet in the AI world, you demand more from humans.
But this isn't true. In my opinion `learning >> depending on an LLM` and my gripe is that it seems like the former is being displaced by the latter. In the pre-AI world I would've known that the person making the mistake wasn't making it because they outsourced their skill.
So I'm not, in fact, demanding anything more than in the pre-AI world.
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.
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.
Well the main difference is precisely that I have a clear opportunity to read and understand the declarative file.
But even if something were to sneak in there, rolling back is now trivial.
Also HN: No idea how this OS works, screw writing proper documentation, just ask Claude to do it! Wee!
You AI babies seriously need to pick a lane.
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.
And that's what's great about NixOS, you just clone nixpkgs and treat it like any other underdocumented software you might work on.
As a software engineer I have an opposing attitude towards this. I work on projects with terrible documentation because somebody pays me to do so or there is a significant potential that I can unlock.
There are significant alternatives to NixOS like bootable containers and OSTree which are more useful and better documented. If Nix project really cares about being competitive and adopt users, they have to document their stuff. They are already going against the grain and ain't nobody has time to put up with their weird language and their subpar documentation.
I mean, I'd argue there is significant potential, but really, for me it's just easy because I've been doing it for 20 years, and documentation is always fundamentally worse than code in some important ways.
> If Nix project really cares about being competitive and adopt users, they have to document their stuff.
This is one of the good/bad things about OSS.. most users don't provide positive value to the project. So do they really want to adopt users? Shrugs but the project is certainly competitive.
C’mon, just drop the “greybeard” act. Nix not having proper documentation is bad practice, period. No ifs buts or howevers, it’s just an objective fact. Good documentation is always (ALWAYS) a net positive, and this is an OS with it’s own unique mindset and way of doing things, good documentation is essential. End of.
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.
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
There's also nixos-shell for ad-hoc virtual machines: https://github.com/mic92/nixos-shell
That's definitely what I want... most of the time.
* declarative mode, where your guest config is defined within your host config, or
* imperative mode, where your guest NixOS config is defined in a separate file. You can choose to reuse config between host and guest config files, of course.
It sounds like you want imperative containers. Here's the docs: https://nixos.org/manual/nixos/stable/#sec-imperative-contai...
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
No, because Nix code is actually composable. These other tools aren't.
NixOS containers are the most convenient way to do this, but those will map the entire global nix store into your container. So while only one app would be in your PATH, all other programs are still accessible in principle. From a threat-modelling perspective, this isn't usually a deal-breaker though.
There's also dockerTools, which lets you build bespoke docker/podman images from a set of nix packages. Those will have a fully self-contained and minimal set of files, at the expense of copying those files into the container image instead of just mapping them as a volume.
I think there's ways you can autoderive a python3 with specific packages from python dependency files, but I can't help you there. I do find AI to be reasonably helpful for answering questions like this: it just might sometimes require a bit of help that you want to understand the answer rather than receive a perfect packaged shell.nix file.
[0]: https://mynixos.com/nixpkgs/option/programs.nix-ld.enable
My rule of thumb: keep a strict separation between my projects (which change constantly) and my operating system (which I set up once and periodically update). Any hard nix dependency inside the project is a failure of abstraction IMO. Collaborating with people on other operating systems isn't optional!
In practice this means using language-specific package management (uv, cargo, etc) and ignoring the nix way.
It's also great for the AI era, copilot is really good with that stuff.
I liked Arch and Ubuntu and Mint and OpenSUSE well enough when I used them first, but once I actually tried NixOS it felt so obviously correct that it started to bother me that it's not the default for everything.
Being able to temporarily install things with nix-shell is game changing, and being able to trivially see what's actually installed on my computer by quickly looking at my configuration.nix is so nice. "Uninstalling" things boils down to "remove from configuration.nix and rebuild".
The automatic snapshots upon each build allows me to be a lot "braver" when playing with configurations than I was with Arch. I was always afraid to mess with video card or wifi drivers, because if I screwed something up and if I didn't know how to get back to where I was, I might be stuck reinstalling to get back to a happy state. This didn't happen that often but often enough to have made me a bit weary about futzing with boot parameters or kernel modules. Because of the automatic snapshots with NixOS, it's much easier (and more fun) to poke with the lower level stuff, because if I do break something in a way that I don't know how to fix, the worst case scenario is that I reboot and choose an older generation.
This is a bigger deal than it sounds. For example, with my current laptop, there was a weird quirk with my USB devices having to "wake up" after not being used for more than thirty seconds, meaning that I might start typing and the first three or four words wouldn't go through. After some digging, I found out that the solution is to add "usbcore.autosuspend=-1" to the kernel params. I did that and it worked.
If I had still been running Arch or Ubuntu, I probably would have just learned to put up with it, because I would have been afraid to edit kernel parameters because of the risk of breaking things in a way that I don't know how to fix.
I love NixOS. I have no desire to leave, or at least I have no desire to abandon the model. I've considered changing to GNU Guix System since I like Lisp more than I like the Nix language, but those FSF-approved distros can be a real headache for people who actually have to use their computers.
This is now a tired discussion; the use of nonguix (https://gitlab.com/nonguix/nonguix) is well documented, there is no practical difference after initial setup between using a regular distro and one of “those FSF-approved distros”
I am sure you don't do it on purpose, but could you stop spreading FUD? (specially given you acknowledge “ I've considered changing to GNU Guix System”, so you're here relaying 3rd party opinions, not your own)
My experience using NixOS on desktop is that it's 95% wonderful, 5% very painful.
If you run into friction with NixOS, you may need to have a wider/deeper understanding of what you're trying to do, compared to the more typical Linux OSs which can be beaten into shape.
With NixOS, you pay all the complexity up front.
I just use apt, been doing it for 20 years, it works great. I've never in my time, heard of or knew anyone who wrote 20 (or any) bash script wrappers around apt. The one year I was painfully forced to use a Mac for work, brew worked similarly to apt, just used it, no need to wrap it with shell scripts.
Comparing highly functional and capable systems like apt and brew to neanderthal technology sounds like hype.
> It's also great for the AI era
That also sounds like more hype, similar to the pro-nix other comments so far which tout AI and similar to the article which I did read, also sounds like hype.
I mean, I'm only ever using it for configurations, and I think I'd still prefer writing Nix than YAML. I probably wouldn't like writing a full "program" with Nix, but I don't think anyone does that?
I have written a lot of PHP. In order to learn it I bought several books, I've done a dozen or so projects with it at various jobs, I've written both trivial and non-trivial things, and I have come to the conclusion that PHP is an actively terrible language [1]. It's inconsistent and hard to write in any kind of maintainable way with an ugly syntax and generally-crappy performance for any kind of logic beyond CRUD.
[1] At least version 5, which is the last version I've used. I've heard 7 is better but I'll never know because I swore an oath in blood that I would not do PHP again for less than a million dollars a year.
People just seem to want to complain because it doesn't look like any of their favorite languages and they aren't familiar with functional languages. At this point, I can't imagine using any other language in place of Nix. The code would have so much noise and be much harder to read.
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?
I've taken a look at the code - having never written a line of Guix in my life - and it seems very readable to me. It's cleanly structured and makes good use of indentation.
The string "))))))))))", which you claim you're seeing 'regularly', appears exactly twice in 4,580 lines of code. It's the longest parens string that appears in the file. Seems to me like you deliberately searched for the most atypical example, that you're now misrepresenting as 'regular', when it is highly atypical.
And honestly, what would that look like in some 'more normal' language?
);
}
);
];
};
)()();
Better?I will never understand this fear response some people have to seeing `(fn a b)` instead of `fn(a, b)`.
And yes your example is better, but still terrible. The point is not the formatting. The point is that there is that 10 deep nested code is just not easy to understand. I would also say a line of c/python that does 10 nested function calls as unreadable. But they do not encourage this, whereas with lisp its modus operandi to write such incantation.
Provided you don't consider the context, sure. One of them is software with buggy tests, the other is one that provides a custom test suite that basically has to be reimplemented in the package definition. How often do you think either of those things happen?
You are projecting a programming style onto Lisps that's quite alien to them. Lisps tend towards small, discrete functions that are composed together. It is the ordinary languages that tend towards deep branching and nesting; Lisps generally favour recursion and function composition instead.
Beside I don't think I'm alien to the functional way of writing things. I write mostly Haskell professionally. But Haskell doesn't casually suffer from making insane expression nesting the default.
I don't think there's much anyone can say that's going to change your mind. You're strongly coming off as though you've formed a view, based on little experience, and will now Ctrl-F cherry-picked examples to sustain it rather than listen to any contrary information. I respectfully suggest greater open-mindedness and a willingness to reserve conclusions in the absence of data.
I personally don't use Lisp too much, so I'm not particularly invested in this exchange, but I know from experience it's not even remotely what you're describing it as. Everything about Lisps tends towards minimal nesting, from the use of paredit to edit expressions through REPL-based workflows.
The only thing this exchange has done, as someone who programs in FP exclusively, is make me reminisce about and yearn for Lisp. It's a wonderful language for FP.
This is not some weird opinion I have. There is a reason "flat is better than nested" is part of the pretty popular zen of Python.
S-expressions were supposed to be replaced by a more user friendly syntax. The trade offs were not worth it and every try to replace sexprs failed.
If it is such a problem you can use wisp to write your packages.
https://www.gnu.org/software/guile/manual/html_node/SRFI_002...
If I then can choose between guix and a language that doesn't require these hoops and extreme quality trade off the choice is not hard.
Anyway if you think guix is better than nix, than nothing stops you from using it.
7 years later I had to write common lisp and I think the parens were a problem for about a week. Since then I have written many thousand lines of lisp code. I usually go back and forth on what I like the most. ML (ocaml mostly) or (guile) scheme. In just about every other language (except maybe factor) I miss the macros (even syntax rules ones) way more than I like the extra expressiveness of, say, Haskell. [0]
Wisp is a part of guile. So you can write your own config using it. It is not completely straightforward, but if you really hate parentheses it is a way. Or you continue the wonderful string gluing of Nix. Whatever floats your boat.
[0]: I do miss typing sometimes in scheme though. I have thought about vibe coding a prototype of an s-expr language that compiles to f# AST.
This isn’t about whether someone can get used to parentheses. Obviously they can. I don’t doubt your extensive experience there. The question is what the language optimizes for by default.
My argument is that S-expressions optimize for structural uniformity and macro power, but they do so at the expense of plain-text readability without tooling. And that trade-off matters in contexts where code is frequently read outside of a fully configured editor—code reviews, diffs, quick inspection, etc.
Saying “editors solve this” doesn’t really address that, it just shifts the burden to tooling. In contrast, many other languages aim to be reasonably legible even in minimal environments.
So I’m not arguing that Lisp is unusable. I’m saying it makes a different set of trade-offs, and for my use case where I spend much more time reading other peoples code in some web portal and with basic terminal tools those trade-offs are a net negative.
If those trade-offs work for you, that’s fine.
That's exactly the part that is wrong with Guix, and Scheme in general. Scheme has associated lists, they are written as '((name . value) ...), but since that's too ugly everybody makes macro wrappers around them to get them down to just (name value). But that means you aren't dealing with an obvious data type anymore, but with whatever the macro produces and if you want to manipulate that you need special tools yet again. And then you have record-type and named arguments which are different things yet again, but all serve the same name->value function as an associated list. Names themselves are sometimes symbols, sometimes keywords, and sometimes actual values. Same with lambda, sometimes you need to supply a function, other times there is a macro that allows you to supply a block of code.
It's like the opposite of the Zen of Python, there are always three different ways to do a thing and none of them as any real advantage over the other, they are just different for no good reason and intermixed in the same code base.
Are you complaining that a language has both associative containers and structs? Which one do you advocate for removing in Python to keep up the precious "Zen"?
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.
https://guix.gnu.org/manual/1.5.0/en/html_node/Inferiors.htm...
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'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.
But I can’t say I recommend it for dev work. It wants you to do everything inside devcontainers, which I like in theory but in practice come with so many annoyances. It wants you to install Flatpaks but Flathub is pretty sparse. I ended up downloading raw Linux binaries into my home directory (which actually works surprisingly well. Maybe this is the future, hah)
I think next time I’ll just go with vanilla Fedora.
> 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 !
Using Nix for per-project development dependencies is quite good. It's nice to be able to return to a project & not have to fuss over which tools/libraries need to be installed.
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 of the years of built up confidence proving that 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."
But trying to set up an environment for one of those perpetually running AIs, and asking it to refactor its own configuration according to some of the high-level abstractions like dendritic flake-parts, and so on, it's just clueless and will improvise without success.
What makes Nix hard for humans also makes Nix hard for AIs: Untyped lambdas that get resolved in some implied out-of-file context means you have to know if you're looking at a NixOS module, a home-manager module, a nix-darwin module, a flake-parts module, and so on. And those modules may make assumptions about what's imported in the parent scope.
So I feel like you need to supply a rather extensive context for your project that details how you want things structured, because the ecosystem is quite fragmented, people don't fully agree on what good patterns are, and so the AI can't know what the good patterns are.
Just to be absolutely clear: I think that supplying an extensive context is absolutely worth it, and I'm having great joy and success building better Nix-based project templates, Nix-based deployment templates, etc. The amount of stable, well-made projects made by other Nix users is just amazing.
https://simonshine.dk/articles/hugo-static-site-setup/
https://simonshine.dk/articles/vendoring-hugo-themes-with-ni...
My blog is deployed here:
https://github.com/sshine/nix/blob/main/services/nginx.nix#L...
I'm sure Nix is better, I just haven't needed it yet.
Since Nix requires a declarative configuration, you need less discipline, but more up-front specification. For example, making truly idempotent Ansible scripts requires a lot of effort and some strong assumptions about your starting state and what processes piped changes into your state, and what your state changes really mean. Also, running your playbook with newer version of the same software may lead to a different result. For example, migrating from bullseye to bookworm with a cargo-deb that contained dependencies: It turned out that there were implied dependencies taken for granted in bullseye that were removed in bookworm. With Nix this will lead to a build error rather than a deployment error or a runtime error (in most cases).
Nix requires fewer assumptions.
> my entire ansible playbook makes server creation a 3 min process
I'm a big fan of Ansible, and everything has its use.
I like to categorize deployment tools as either "bottom-up" or "top-down" depending on what assumptions you make about the world: Ansible fills the slot where you have no control of how the server got there, but you gotta make use of what you have, and start from scratch. Terraform is the canonical bottom-down tool: You assume you have perfect control of what gets provisioned, and that it won't go away or go out-of-sync without active maintenance.
In this top-down/bottom-up topology, Nix can fill the whole spectrum; most people assume Nix/NixOS is available to them, at which point their automation starts. Others deploy NixOS via various automated processes that can be integrated with both top-down or bottom-up solutions, e.g. distribute via network boot, VM image repository, or via "hostile takeover" (deploy on existing Linux machines via SSH, like Ansible, or using Ansible).
Same goes for the harness itself. Want to know how Codex works or whether it can be configured in some way? Clone it and ask it to look at itself.
But the cut-off point in model / harness quality before it hallucinates everything but the general Nix syntax is staggeringly low.
I knew my flake setup could be better but never bothered. Then one day earlier this year I threw Claude at it. Not only did it improve everything, it fixed a small bug that had been bothering me.
My confidence in doing this came from exactly what you said: If it blows everything up I can just rollback.
Immutability and rollbacks are merely nice side effects of the Nix model.
Nix and AI is a match made in heaven and I think we’re going to see a lot of good software that’s amenable for us by AI that is both cheaper to build and easier to use.
I had Claude do the grunt work of shifting parts of my config to a new structure I started but didn't have time to fully implement.
Based on examples I provided, I had Claude use specialisations to set up a couple of different WM and DE test environments.
And the thing is that, now that I have everything set up the way I want, I don't really have to DO anything to keep the system running, other than occasionally update (I'm on unstable, so I do that manually).
Could I turn Claude loose on my .config directory, give it access to apt or dnf (etc.), and let it set up a non-NixOS environment for me? Probably, and it would probably work reasonably well, but I wouldn't trust it the way I trust NixOS.
Anyway, it turns out this is a perfect setup for an AI bot to step in: it's got all those forum posts to learn from and it's endlessly patient when it comes to just figuring everything out from the source code.
It does tend to hallucinate but thats the great thing about nix... if it builds its probably right!
Hey now, LLMs are pretty good at Guix, too.
Even messing with stdenv or language builders is trivialized. Any software that I want, I can get within a few hours of claude/codex just spinning unsupervised. It's so nice! Underrated for sure.
Reverting changes are guaranteed to not leave behind any cruft, and you don't have to remember what you changed to make X or Y work: it's all visible in the (usually version controlled) system configuration.
Got a new computer? Just copy the configuration and enjoy a bit-identical system in seconds. Have an LLM tweak it and see the changes in the form of git diffs.
Sure, you can do the same with Silverblue and writing Ansible for everything, but it's not free of side effects (unlike Nix).
Not an argument against using NixOS - I think the bridge device issue could reasonably be regarded as a bug rather than a fundamental design issue, and the user id/username mapping is a totally reasonable design decision which can be taken into account by forcing the user id numbers anyway.
One reason to set `mutableUsers = false`: https://mynixos.com/nixpkgs/option/users.mutableUsers.
> And if you activate and enable incus, for instance, it will probably create a bridge device: the device will remain in place after you remove incus, which will have implications for how your network/firewall works that your configuration will depend on but will not enforce or be able to reproduce.
Impermanence: https://github.com/nix-community/impermanence.
To be clear, I don't use neither. But you can get NixOS to be almost completely stateless (if this is something you care) with a few changes. The power is there, but it is disabled by default because it is not the pragmatic choice in most cases.
That doesn't help. Mutable users is about the lifecycle of the /etc/passwd file. What's I'm referring to is /var/lib/nixos/uid-map.
Rollback is already very easy with filesystem snapshots. Configs are already tracked by etckeeper. New laptop: either copy the whole drive or the package list and dotfiles. Also, how often do you have to get new laptops for this to be relevant ?
NixOS gives you that just by opting in to using it, and while AI also speeds up config changes and translating your existing knowledge to a new tool you're trialing in other distros as well it really shines with NixOS where you don't even have to care what it messes up while you're trying something new. You just revert and you know that nothing that was done to configure that new thing - which likely would have broken your existing configuration on other distros - has persisted.
(1) Take a snapshot of your current system (snapper+btrfs on Linux, bectl on FreeBSD+ZFS)
(2) Make destructive changes like install a new windows manager, some drivers etc.
(3) If everything worked out well, continue
(4) If something failed badly, restore from (1) using the snapshot restore -- Your system is as good as before
This workflow replicates many of the benefits of NixOS without the complex nix scripting that can be often needed.
Of course, a declarative and textual rendition of the configuration is better than bash commands entered on the command line but sometimes you don't need that level of precision.
But note that I did caveat my suggestion: "Of course, a declarative and textual rendition of the configuration is better than bash commands entered on the command line but sometimes you don't need that level of precision."
There is no distinction between package maintainers and end users. They have the same power.
In the meantime i dont expect Debian users to ever write a package themselves or to modify one.
In nixOS you do it all the time
# clone the package definition
$ fedpkg clone -a <name of package>
$ cd <name of package>
# install build dependencies
$ sudo dnf builddep ./nameofpackage.spec
# Now add your patches or modifications
# now build the package locally
$ fedpkg local
# install locally modified package
$ sudo dnf install ./the-locally-built-package.rpm
Let me put it differently. The documentation of NixOS treats package maintainers and users as kind of equal.
This has benefits and downsides. Benefit is that everyone is treated as a power user. Downside is that power users are horrible at writing docs and this philosophy is my main theory why NixOS docs are so .... Bad
Fedora (and RHEL) end user and developer docs are written for quite different audiences
(As for why the docs are so bad, I think it's because of the lack of good canonical documentation. There's too many copies of it. Search engines ignore the canonical version because it's presented as one giant document. Parts of the system aren't documented at all and you have to work out what you've got by reading the code. The result is that you have no idea what to do if you want to improve the situation - it seems like your best option is to create new documentation. And now you have the same basic level of documentation that didn't help the first hundred times it was rewritten. And I don't really think submitting a PR to nixpkgs is exactly userfriendly, so it probably discourages people from doing the "I'm just trying to understand this, so I'll fix up the documentation as I learn something" thing.)
You're in no way bound by decisions of the nixpkgs contributors: as you say, we can add a patch. Or we can also decide we totally disapprove of the way they've configured such-and-such a service and write our own systemd service to run it.
Anyone can write a local debian package which adds a patch, and build and install it. And anyone can write a systemd service and use it instead of the distribution's systemd service. But on NixOS, these are equal to the rest of the system rather than outside it. Nixpkgs is just a library which your configuration uses to build a system.
People who get bogged down by the details of examples/analogies are usually missing the point of why people use examples/analogies.
programs.hyperland.enable = true
is your dnf equivalent on nix. But nix also lets you declare all your key bindings, load Noctalia with systemd, etc.
And, critically, at no point does an LLM ever have access to sudo, shell, etc.. It just works with plain text files that aren't even on the machine I'm deploying it to.
But it isn't necessary. You can certainly make a change and apply it without committing it to git or relying on a CI/CD pipeline to deploy it. And it isn't necessary to use input pinning - if you don't, you can wind up making it at best archaeological work to rollback. Most people recommend flakes nowadays though, whose input pinning and purity rules should prevent any need for archaeology if you do commit before applying.
Automating my homelab config with coding machines not only hides the jank, but also makes NixOS feel like some actual agentic OS Microsoft wants, or rather an ad-hoc prototype. I literally just tell it what to do and describe issues if I have any. But again I have written a ton of Nix previously and I'm able to verify what it does, most of the time it's correct but it's not perfect.
Coding agents actually help with a lot of the ergonomic issues. If you have an evaluation issue, it can be annoying to climb into nixpkgs to diagnose it. But codex will do that for you.
I’ve found agenix in particular to be really great addition for agents: secrets you can copy around without risk of accidental disclosure.
In a day I can now deploy Caddy, Authentik, Fleet, Headscale, Stalwart, jmap-webmail, Forgejo, SFTPGo, Immich, Grafana, Jaeger, PostHog, etc. and have them all work together. I can do this on a tiny VPS, and codex can actually estimate and test performance to minimize cost.
The equivalent Kubernetes setup wastes so much on isolation and a scheduler that is overkill for anything small.
My first impression after a week of using:
- I really dislike the complexity of terraform, and this is very similar
- The UX is pretty bad, the commands and flags are hard to memorize and you basically need a shell alias for any regular commands to clean them up
- The commands you run regularly like applying your nix config to the system after adding some new packages or config options look like: "nix run nix-darwin -- switch --flake /Users/philipp/repos/github.com/dewey/nix#private"". The output is a mix between expected warnings and way to verbose for something that should essentially be the equivalent of "brew update / brew upgrade".
I'll stick with it as I didn't find anything better and LLMs are great for building up the config over time, but there's definitely room for some improvements.
On the one hand, it's great, as so many others here and TFA have attested. Declaratively specifying your system configuration and using snapshots to keep track of everything is a complete game-changer. Similarly great is the absolutely huge universe of installable packages. The coverage here is so much better than what's on offer from Ubuntu or Fedora.
On the other hand, the current implementation is still a bit of a shit-show.
First, there's nix-the-OS and nix-the-package-manager which is pretty confusing. Effectively it means you manage your OS with one declarative system and your local/home config with another. Then there's "Flakes" which I never quite understood, that seem to offer a different modality altogether.
Second, installing packages is nice, but also confusing. Do you install a package or a service? Often both are available and the difference is not always clear. Eventually I learned to choose a service whenever one was available. In either case, the tendency of package maintainers is to install the smallest possible version of whatever you asked for. For example, I wanted KDE but what I got was a bare minimum version with plenty of missing apps and functionality that could only be fixed by adding extra components, one at a time, after debugging whatever was currently breaking.
I appreciated that services and packages can be configured in the configuration file. But the options exposed are usually a partial set of what's available -- without extending the installations scripts yourself. So now my "declarative" config is a mix of what's in my nixOS config file and what's in my manually edited /etc files.
Third, the documentation, mentioned by others, is a mess. There's all kinds of information about old and new versions. The interfaces of the command-line tools seem to have changed between the 25.05 stable that I chose and the then-upcoming 25.11, which made following-along harder than it needed to be.
I eventually gave up because I needed a working machine and not a new hobby. I was left with the impression that NixOS might be a good choice for system admins, but perhaps not yet ready for desktop Linux users.
> there's "Flakes" which I never quite understood
Nix never clicked for me until I started using flakes. There's a lot of internal drama surrounding them that honestly childish; that's why they are marked as experimental and not the official recommendation. You are going to have a worse time with Nix if you go with the official recommendation, flakes are significantly more intuitive. The Determinate Systems installer enables them by default, and whatever documentation they have is on the happier path (except for FlakeHub, I haven't figured that one out yet).
On the most fundamental level, flakes allow you to take /etc/nixos/nixos.nix (or whatever, it has been forever) out of /etc and into a git repository. Old-style nix may be able to do that, but I discovered flakes before trying. I did previously attempt to use git on /etc/nix, but git was falling to pieces with bizarre ownership problems.
What this means is that I could install and completely configure a machine, once booted into a nix iso, by running: nixos-install --flake https://github.com/.../repo.git. I manage all of my system config out of /home/$user/$clone
As for /home there is home-manager and, again, you are not steered towards it (the tutorial pushes you towards nix profiles/nix-env instead). Home-manager will do for your home directory what the system config does for your system, and has many program modules. You can even declare home-level systemd units and whatnot.
> manually edited /etc files.
You can use environment.etc for these files[1]. systemd.tmpfiles can be used for things outside of etc. Home-manager has the equivalent for .config, .local, .cache. [2].
[1]: https://search.nixos.org/options?channel=unstable&query=envi... [2]: https://home-manager-options.extranix.com/?query=xdg.configF...
Flakes do 2 things:
1. Declaration of the inputs and outputs of some Nix codebase. 2. Pinning the versions of this input sources.
The dependency pinning is similar to package.json/package.lock etc. which are common in language-specific package managers.
https://discourse.nixos.org/t/how-to-manage-dotfiles-with-ho...
> Hi, I just wanted to know, where can I find the documentation to know more about this contrib.lib.file.mkOutOfStoreSymlink option ?
> Well, since is a very simple function, no documentation is really needed.
I've been gradually transitioning everything to NixOS, starting with my homelab mini PC, then my Framework laptop, and now my daily driver desktop. It's hard to imagine going back because the pros are so strong compared to the cons, but the docs situation is truly dire.
It’s a solid os, and I’m enjoying it, and I love that I can’t break things while tweaking. But the docs are and discussion threads are not written for beginners (it’s really hard to write for beginners).
> Do you install a package or a service
A package is like the raw software installation. So eg the bash package is just a wrapper around building bash from source (theoretically from source at least... you can also define a package as being a binary distribution as long as you specify the content hash). The service (actually the _module_) is for everything else around software installation. So, eg, the bash _package_ will build bash and have it available for you to put in your path but the bash _module_ might also configure your .bashrc and set it up as your users shell. It would also generally refer to the bash _package_ so you can do all that plumbing but specify a certain version of bash you want to use.
Another common example: a plex package would again build the plex software but a plex module would perhaps create a plex user, setup systemd units, open your firewall, and create a media directory.
EDIT: the next layer of confusion is that modules (which sort of are a secret-sauce of nix and so naturally you will want to use them a bunch) are specific implementation details of multiple subsystems in nix. Meaning, nixOS and home-manager and nix-darwin all have "modules" but they are not compatible. Each has its own "idea" of what modules are and nix itself doesnt provide this natively. That means things get a little more complicated/involved when you use those ecosystems together. Its not too bad but it is annoying.
You can set dconf settings more declaratively: https://tangled.org/jonathan.dickinson.id/nix/blob/7c895ada8...
It took me less than a day of experimenting with it to learn that it is one place only in theory.
The second you start googling „how do I install xyz“ you discover there are also flakes. And others have some sort of convoluted git like method. And there is a package manager thing. And the direct config file editing like in this article. And a disposable temp install of some sort. And naturally software guides don’t give you instructions for all - they’re opinionated.
Felt a lot like being on Debian and the software only comes in .rpm
That really took the wind out of my sails because like OP I liked the basic config file part
If I'm running a package on a server that means I want to install it declaratively, so I find the name of the package in Nixpkgs and put it in my `configuration.nix` file. I'm using flakes, but the configuration is exactly the same, I just put the package in the output section of the flake. Any instructions you see to install a package just boils down to finding the name of the package. To me this is as simple as finding the name of a Debian package and running `apt` to install it.
If you want additional features there are other optional ways to install packages, but these are features other distros don't offer, so if you just ignore them then there's no extra complexity compared to Debian for example.
Web3, Rust, NixOS. The holy trinity of cult-like appreciation. I do wonder what brings forth such fanaticism.
In the case of a fire, I'm sure you wouldn't prioritize your laptop with NixOS over your cat (let's imagine that the only backup is in the house that's on fire).
Nowadays I love it, since I can let Codex manage the servers for me.
“Here is the flake, here is nix module for the server, here is the project source code. Now change all of that so that wildcard certificates work and requests land through systemd socket on a proper go mux endpoint. Don’t come back until you verify it as working”
5 minutes later it came back.
I see an article like this about how great it is, think I might try it, then go down a rabbit hole of all the horror stories, and then give up before starting.
Declarative, but not trying to solve for the "I want 5 versions of python at the same time" problem. The weird NixOS filesystem is where 90% of my Nix issues come from. And I don't feel like I benefit from it much, if at all. Bonus points if this fictional solution doesn't use a fancy new programming language. Something like HOCON would be perfect.
I just want the same OS, packages and config on all my machines without allowing long-term drift. And I want the time I spend tweaking my Linux setup to be an investment, not a waste of time that gets thrown away when I upgrade. I know I could use home-manager or similar for my user-level config, but that's not enough.
I've been experimenting with the immutable fedora-bootc images and podman+Containerfiles, which works pretty well for this. But there's no "nixos-rebuild switch" command, so changes require a reboot. Fine for daily use, but very painful when experimenting. I did discover its possible to use the older dnf4 --transient flag to temporarily install packages, which is helpful.
I guess its a trade-off between easy tinkering (Nix) but frustrating filesystem vs fussy tinkering (bootc) but standard linux filesystem once booted.
However, AI is a great fit to write flakes. You can easily understand the generated code and it gives a power to "review" the changes before applying them.
And while nixos is amazing, I think nixpkgs are a bit overhyped; I've encountered many packages that are abandoned and outdated.
I can share my configs if anyone is interested.
The language is "interesting" and I haven't had to learn it in depth yet. Claude and Codex really make it easier to get started with Nix's weirdness -- but that's unfortunate because I feel I'm not going to learn the "real thing" otherwise. And this difficulty makes me curious about Guix though because, even though I'm not LISP expert either, at least I can read it.
Anyway. I'm just shy to "dig deeper" on NixOS because my servers are FreeBSD and I'm already feeling the temptation to swap them with NixOS, which would feel like a betrayal to these long-lived installations... ;-P
I found that this gives a good compromise of being able to learn Nix relatively well, but still having a "tutor" to help when things get tricky. I'm reasonably ok at Nix now, and can generally figure out what I need to do without AI assistance, but I'm glad I had ChatGPT when I was getting started with it.
Most of the comments here seem to be from people using NixOS on a laptop. NixOS as a production OS in the cloud or on a robot is a game changer.
soumyaskartha•1d ago
Daunk•1d ago
Imustaskforhelp•1d ago
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)
Diti•1d ago
jwiz•1d ago
That is in between "use it for very short period of time" and "use it forever"
DanielVZ•1d ago
troad•1d ago
I feel like it's more of an indictment than praise; it implies Nix is relatively inaccessible to interested but time-constrained dabblers, which puts a hard cap on Nix's ability to outgrow its niche.
hrmtst93837•1d ago
JamesSwift•13h ago
dizhn•1d ago
ux266478•19h ago
I'd much prefer just Plan 9. WORM filesystem and first-class namespaces.