I Love Nix, But I'm Not Good at It
Look, I've been using NixOS as my daily driver for a while now. I have a flake that builds my system. I have home-manager configs. I have dev shells for my projects. I use nix-shell for throwaway tooling. I'm bought in.
And I still can't write a derivation from scratch without looking things up.
Every time I need to override a package, or compose two flakes, or figure out why my overlay isn't being applied correctly, I end up in this loop: read the docs, read someone's dotfiles, read the nixpkgs source, try something, get a type error that means nothing to me, try something else. Repeat for 45 minutes until it works and I'm not entirely sure why.
Then I started using Claude Code for my Nix configs. And honestly? It nails it on the first or second try almost every time. Overlays, cross-compilation, module options, flake-parts โ stuff that takes me an hour of fumbling, the agent just... writes. Correctly.
Why This Used to Bother Me
My first reaction was embarrassment. I've been in this ecosystem for years. I should be better at it by now. If an AI can do it, what have I been doing with my time?
But then I thought about it differently. Nix is a language where:
- The type system is dynamic and the error messages are famously unhelpful
- The documentation is scattered across the manual, wiki, Discourse, and random GitHub repos
- The "right" way to do something changes depending on whether you're in flakes or legacy nix, which nixpkgs version you're on, and which helper library you're using
- Pattern matching is implicit, attribute sets are everywhere, and the evaluation model is lazy in ways that surprise you at the worst times
This is not a language that rewards occasional use. It rewards either daily immersion or having perfect recall of 10,000 examples. I have neither. The agent has the second one.
What the Agent Actually Has That I Don't
It's not that the agent is smarter than me at Nix. It's that it has seen more Nix than me. Way more. It's been trained on every flake.nix on GitHub, every nixpkgs PR, every NixOS module definition, every Discourse thread where someone solved the exact problem I'm hitting.
When I ask it to "add a Python package that isn't in nixpkgs using buildPythonPackage," it's not reasoning from first principles. It's pattern-matching against thousands of examples of people who already did that exact thing. And pattern-matching is what Nix demands โ because the documentation is often just "look at how other packages do it."
That used to be the advice humans gave each other on the Nix forums. "Just grep nixpkgs for an example." The agent has internalized the entire grep.
Here's What I Actually Do Now
๐ Takes about 5 minutes for most Nix tasks that used to take me an hour.
1. I describe what I want in plain language
"Add a dev shell to my flake that has Python 3.11,
poetry, and a PostgreSQL client. Make sure the
Python packages can build native extensions."
2. The agent writes the Nix
It gives me a proper devShell with mkShell, the right buildInputs, the LD_LIBRARY_PATH dance for native extensions, and usually a shellHook that activates a venv. First try.
3. I read what it wrote and learn something
This is the part that matters. I'm not blindly copying. I'm reading the output and going "oh, THAT'S how you set lib.makeLibraryPath for native extensions" or "I didn't know you could use nixpkgs.extend like that." Every interaction teaches me something I would have spent 30 minutes discovering on my own.
4. I ask it to explain the parts I don't understand
The agent is also really good at explaining why a particular Nix pattern works. "Why did you use callPackage here instead of just importing the file?" gives me a better answer than most docs pages.
This Is Actually How You Learn Nix
Here's my possibly controversial take: this is the correct way to learn Nix.
Nix has always been a language where you learn by reading examples. The documentation is incomplete. The type errors don't help. The community advice has always been "read nixpkgs source." The learning method was always pattern-matching โ it's just that before agents, you had to do the pattern-matching yourself, slowly, by grepping through thousands of files.
Using an agent for Nix is like having a senior Nix developer pair-programming with you who never gets tired of your questions. That's not cheating. That's the learning environment most Nix users have always wanted and never had.
Where the Agent Still Gets It Wrong
It's not perfect. Some patterns I've noticed:
- Stale patterns โ Sometimes it suggests the pre-flakes way of doing things, or uses deprecated lib functions. You still need to know enough to spot this.
- Overcomplicated solutions โ It sometimes reaches for overlays or overrides when a simpler approach would work. I've learned to ask "is there a simpler way?" as a follow-up.
- Cross-system issues โ It occasionally forgets about the aarch64/x86_64 distinction or suggests patterns that don't work with flake-parts specifically.
- Novel combinations โ When you're doing something truly unusual (combining three niche tools in a way nobody has blogged about), it hallucinates plausible-looking but wrong configurations.
So you can't abdicate understanding entirely. But you can let the agent handle the 80% that's "standard Nix patterns applied to your specific packages" and focus your own brain on the 20% that's actually novel.
Why I'm Obsessed With This Approach
- I actually finish Nix tasks now โ Instead of getting stuck in a docs spiral and switching to Docker out of frustration
- My configs are better โ The agent writes more idiomatic Nix than I do because it's seen more of it
- I'm learning faster โ Reading correct Nix with explanations beats struggling alone with bad error messages
- I stay in the ecosystem โ The barrier that keeps people from adopting Nix (the learning curve) is dramatically lower
- I can focus on the decisions โ Should this be a devShell or a package? Should I pin this or follow unstable? Those are the interesting questions, not "what's the syntax for an override"
The Bigger Lesson: Tools Should Cover Your Weaknesses
There's this weird machismo in programming where you're supposed to be embarrassed if a tool does something better than you. As if your value comes from memorizing syntax instead of making good decisions about systems.
I know what I want my Nix configs to do. I know the architecture. I know which packages I need, how my dev environment should behave, what my deployment pipeline requires. That's the hard part. The agent handles the translation into Nix's specific syntax and idioms. That's the easy-but-tedious part that I happened to never fully internalize.
This is true for Nix specifically because Nix is a language most people use occasionally, in bursts, for configuration rather than application logic. It's the kind of thing where the agent's advantage (having seen everything) matters most and your advantage (deep familiarity from daily use) matters least.
I'm still the one who decides we're using Nix at all. I'm still the one who designs the system architecture. I'm still the one who knows what reproducibility guarantees we need and why. The agent just helps me express those decisions in a language I use fluently enough to read but not fluently enough to write cold.
Try This Today โก
If you've been avoiding Nix because the learning curve felt too steep, or if you're like me and you use it but never feel confident:
- Take one project that uses Docker for dev โ ask your AI coding tool to write a flake.nix with a devShell that replaces your Dockerfile
- Read what it generates โ don't just use it, study it. Ask "why did you do X instead of Y?"
- Run
nix developand see if it works โ if it doesn't, paste the error back. The agent is usually great at debugging Nix errors because it can pattern-match the error to the fix
You'll get a working Nix dev environment in 5 minutes instead of 2 hours. And you'll understand it better than if you'd copied it from a blog post, because you can ask follow-up questions.
Good enough Nix that works > perfect understanding you never achieve. Ship the flake.
Header image by Bozhin Karaivanov on Unsplash
Content on this blog was created using human and AI-assisted workflows described here. Original ideas and editorial decisions by Justin Quaintance.