If flakes are experimental, what's the experiment?
tl;dr ¶
You’re in luck: flakes aren’t real, so none of this matters!
Summary ¶
- “experimental” originally meant “we’re still evaluating the technical stability”
- the experiment has ended, but the outcome of whether the experiment succeeded cannot be expressed
- since the community has diverged on whether the experiment succeded, we cannot answer it in unity
- on the one hand, flakes are obviously a success: they’re widely in use throughout the gitverse
- on the other hand, flakes are a failure: they scope creep and the attempts to finalize them died
- ironically, flakes become a social experiment in open-source governance instead of a feature experiment
- meanwhile, the technical limitations of flakes appear to get resolved independently as they get reimplemented
- what’s missing is unity: a dozen solutions to a dozen sub-problems under a dozen names; gathering is needed
- what flakes provides is a banner for joined effort; since they’re divisive, the post-flake movement is born
- the dendritic patterns happens to align with the post-flake movement because it is catchy and researchy
- flake-parts already offers “top-level configurations” with no dependency on a contended runtime — the technical building blocks are in place
- libraries can’t solve convergence; new Nix users all follow the same flowchart and hit the “flakes: experimental or cool?” fork
- a more radical move than merging flakes would be to remove them from the Nix CLI entirely — that levels the playing field for alternative implementations
- the massive existing adoption of flakes will have to live behind the feature flag forever; the experiment is over, “we all won”, and the question becomes move on to what?
- the post-flake movement reframes flakes as a design pattern you can disassemble, with flake-parts as the strongest common denominator
- the work currently lives inside the Denful “research vessel” — it needs to eventually dock and feed solutions back, untangled from old politics
- flakes are defined by their implementation (which is stalled and flaky at the edges); flake-parts has a shape but flake-schemas aren’t standardized beyond Determinate Nix
- a call to revive interest in writing an actual specification for flakes
Story Time! ¶
(Skip this section, this is just me ranting about discovering new design patterns.)
This year I have officially taken over the role of terranix maintainer, as well as the ownership of the terranix.org domain. This is the first open-source project with real users that I’ve been responsible for after 30 years of being an open-source consumer. To celebrate, for the purpose of dogfooding, and to provide another example usage for documentation, I decided to maintain DNS records for terranix.org with terranix and deSEC.io.
Since I declared the novelty budget dead, and because I’m already sold on the dendritic pattern, I decided to complicate the project flake with flake-file and found myself wasting the whole evening just tinkering with inputs and outputs and reading source code. I rabbit-holed deeper on unflake and trix since they were mentioned on the Nix Freaks podcast. None of these are really as simple as flakes: Flakes are a recognizable pattern with a known starting point for reading, where I don’t have to decode the author’s domain-specific language.
So here I am in 2026, exactly one year after Shahar coined the term dendritic and Vic picked it up and ran with it.
There are dozens of contributors to flake-alternatives that offer various degrees of flake compatibility, some of which
don’t require the experimental feature to be enabled, some which entirely replace parts of flakes (e.g. input pinning),
soften the input deduplication (no nixpkgs_7, nixpkgs_8, …), allow for other version-control systems
than git.
While the typical dendritic invocation is via flake-parts and import-tree, the dendritic pattern extends flakes by saying flake-parts modules are just one kind of “top-level configuration”. Projects like Vic’s with-inputs, aanderse’s trix, Max Siling’s unflake, toastal’s nixtamal: they experiment with “the flake space”, by not requiring experimental feature flags.
What’s an experiment? ¶
The Nix Reference Manual defines an experimental feature this way:
An experimental feature enables developers to iterate on and deliver a new idea without committing to it or requiring a costly long-running fork. It is primarily an issue of implementation, targeting Nix developers and early testers."
While flakes don’t live in a git fork, they do fork the community.
TODO: unpack these theses ¶
- TODO: unpack what “experimental” originally meant — “we’re still evaluating if this is nice or not” — vs. what it has come to mean in practice (“the feature flag isn’t moving”)
- TODO: unpack the failure side — scope creep of flakes, and the attempts to finalize them that died (CCR, RFCs, etc.); right now the article only gestures at “limited incentive to improve on those deficiencies”
- TODO: unpack the thesis that flakes became a social experiment in open-source governance rather than a feature experiment; the body only hints at this with “socio-technical” and the “I quit politics” aside
- TODO: rework “widely in use throughout the gitverse” — either justify the framing or drop it
- TODO: sharpen “the outcome of whether the experiment succeeded cannot be expressed” — currently the body says the community diverges, but not that the question is structurally unanswerable
Can you get flakes without --experimental-features flakes?
¶
It turns out you can!
You just have to spend a dozen hours reading research-grade code
Ironically, this is a lot more experimental in the real sense of the word than enabling a built-in feature flag.
By now, the Nix community is diverging on whether flakes are experimental or not: They’re widely used, they’re considered stable by Determinate Systems (who employ Eelco), they have well-known deficiencies that keep them locked behind the feature flag, and there is limited incentive to improve on those deficiencies.
It should be clear that “experimental” here means “the feature flag is not moving further as it is”. The problems advancing flakes within the Nix CLI are socio-technical and more complex than just performance-optimizing lazy functional runtime semantics. They’re feature-complete by some standard, and have immature runtime characteristics by others.
I personally quit politics after it consumed my teenage years. I like technical stuff now.
And so I’m driven to these post-flake solutions even though they cost a lot more time to understand.
unflake ¶
TODO: A quick intro to getting started with unflake and how it looks like
trix ¶
TODO: A quick intro to getting started with trix and how it looks like
Let’s end the experiemnt ¶
flake-parts provide “top-level configurations” with no dependency on contended runtimes.
There are several ways to execute them, with or without experimental features, with or without actual experimenting.
What libraries can’t solve, however, is convergence: People who begin using Nix all follow the same flowchart initially:
- Install Nix or NixOS
- Find home-manager
- Get confused why home-manager modules aren’t NixOS modules
- Find out flakes exist
- Either assess “they’re experimental, I’m overwhelmed enough as it is!”
- Or assess “Flakes sound cool, all my favorite projects seem to use them
I happened to start my Nix career with a colleague who pushed flakes hard. At the same time, I was overwhelmed by a very steep learning curve of bare-metal Rust and setting up on-prem CI for cross-compilation on NixOS. So I pulled the brake on flakes for some weeks. Over time I use them everywhere because I trusted that my colleague had good taste.
What would happen if, instead of merging flakes in the Nix CLI, we removed them entirely?
They’d stop being “experimental” and better implementations would get an even playing field.
The real, massive adoption of flakes would have to accept they live behind an experimental feature flag, and the experiment is over. We all won. But we need to move on. To what?
Call for unity ¶
The post-flake movement is viewing flakes as more of a design pattern than a hardcoded feature inside a CLI. A pattern you can disassemble and use parts of, but with strong common denominators, especially focused on flake-parts. The immediate benefit of using shared patterns is recognizability and reuse of other people’s strong ideas.
But since the post-flake movement currently lives mostly inside a research vessel called Denful, it’d be lovely if this vessel could eventually dock somewhere and give back technical solutions untangled from the politics from five years ago.
- Flakes are defined by their implementation, but the implementation is a stalled experiment and is flaky at the edges
- Flake-parts have a recognizable shape, but [flake-schemas][flake-schemas] are not standardized beyond Determinate Nix
Maybe there can be renewed interest in defining a specification for flakes.