A feature now adopted by most Nix users, and recommended by default in a large share of open source projects, still carries the official “experimental” label seven years after introduction. That feature is flakes. At Hebeko we regularly work with Nix environments for clients, and this status ambiguity comes up every time technical teams evaluate the tool. This article sets out the terms of the debate and its points of conflict.
The problem flakes solve
Nix stands out from other package managers with a strong promise: giving the same expression to two different machines must produce a strictly identical result, bit for bit. That promise is one of the main arguments for adopting Nix in the enterprise, especially for teams that care about traceability and compliance of production environments.
Before flakes, that promise still had a gap. Nix projects relied on channels: global, mutable channels that could differ from machine to machine, and on a search path (NIX_PATH) whose resolution depended on the local environment. Two collaborators working on the same repository could get different build results without changing any code.
How flakes work
flowchart LR
A["flake.nix<br/>declares inputs<br/>(nixpkgs, third-party flakes...)"] --> B["flake.lock<br/>pins each input<br/>to a precise commit"]
B --> C["Bit-for-bit reproducibility<br/>nix develop produces the same<br/>environment everywhere"]
In 2019, Eelco Dolstra, creator of Nix, proposed flakes in response. The idea rests on four elements:
- A
flake.nixfile that explicitly declares a project’s dependencies. - A
flake.lockfile, generated automatically, that pins each dependency to a precise commit. - A so-called “pure” evaluation, independent of environment variables and local machine state.
- A standardised output structure (
packages,devShells,nixosConfigurations) that makes any project immediately understandable by another team, without extra documentation.
For an organisation, cloning a repository and running nix develop is enough to get a development environment identical to the author’s, with no manual install steps.
A lasting disagreement in the community
That gain never produced consensus in the Nix community. The disagreement informs the precautions to take for enterprise adoption.
First friction: how the feature was introduced
Part of the community reacted badly to the fact that the initial RFC for flakes was abandoned mid-way, while the feature itself was still integrated into Nix. Other contributors were not opposed in principle to shipping experimental features without a formal RFC (common practice in the project), but criticised that flakes never really behaved as experimental: little rollback, little deep redesign, and adoption so fast that any breaking change became politically hard to own.
Second friction: contested design choices
flowchart TD
P["Your project"] --> A["Flake A<br/>nixpkgs @ a1b2"]
P --> B["Flake B<br/>nixpkgs @ c3d4"]
P --> C["Flake C<br/>nixpkgs @ e5f6"]
A --> W["Three distinct nixpkgs copies<br/>build time and disk space potentially multiplied"]
B --> W
C --> W
Several users report concrete operational friction. Each third-party flake can ship its own nixpkgs version: if a project depends on three unharmonised third-party flakes, each may bring its own nixpkgs at a different commit, multiplying build times and disk use. Tight coupling with Git is another frequent trap for newcomers, who must git add every change before rebuilding or see it silently ignored. These two points lengthen development time and should be anticipated in a professional setting.
Third friction: a design seen as too specific
Some critics argue flakes were originally designed for a single client’s needs, and that prolonged experimental status reduces the chance that implementation gaps will be fixed. The argument can be polemical, but it recurs in technical discussions and cannot be dismissed without examination.
The defenders’ position
Flake advocates answer these critiques. Graham Christensen, co-founder of Determinate Systems (where Eelco Dolstra also works), has long argued that flakes are already stable in practice, and that the experimental label should never have lasted this long. His summary: the most common critiques (nixpkgs duplication, lack of native cross-compilation support, lockfile format) are either misframed, unrelated to flake design, or already being addressed. His company also ships a Nix distribution where flakes are marked stable by default.
Most current Nix users also use flakes, de facto usage that weighs when judging their maturity.
The institutional compromise: RFC 0136
Nix project governance tried to exit the impasse with RFC 0136. It first sets general principles for Nix evolution, then defines a progressive stabilisation plan: first the CLI, then flakes themselves, whose final design still needs another RFC.
The author explicitly asks “flake sceptics” not to reopen the design debate, to avoid reproducing long, inconclusive discussions from the past. That precaution alone shows how much tension has accumulated.
The RFC also recognises that flakes are widely adopted by new Nix users, to the point of being de facto majority usage, which limits room for any redesign.
Recommendations for enterprise adoption
Our recommendations for an organisation evaluating flakes:
- Adopting flakes is not, at this stage, a risky technical choice. No stakeholder, including the critics, seriously contemplates abandoning them.
- The “experimental” label mainly protects against targeted breaking changes, not against removing the feature. Enable the setting explicitly (
experimental-features = nix-command flakes) and follow announced lockfile changes. - Git coupling is the main friction for teams new to Nix. An unstaged change does not exist for the tool.
- Third-party dependencies need particular vigilance, especially poorly maintained ones. They often carry more risk than flake design itself.
Where the debate stands
The flakes debate is not about to close. Both camps defend a legitimate demand: rigor in the stabilisation process for some, recognition of already massive usage for others. For an organisation evaluating Nix today, knowing this context lets you anticipate friction instead of discovering it mid-project.
Hebeko helps teams adopt NixOS and flakes in production. See NixOS at Hebeko or contact us.
---
Sources
- RFC 0136, "A plan to stabilize the new CLI and Flakes incrementally", NixOS/rfcs
- Full text of RFC 0136
- Community discussion, "Development shells with Nix: four quick examples", Lobsters
- Community discussion, "NixOS RFC 136 approved", Hacker News
- RFC 0049, "Flakes", original proposal by Eelco Dolstra
- Graham Christensen, "Experimental does not mean unstable", Determinate Systems
- Discussion, "Why are flakes still experimental?", NixOS Discourse
- Official documentation, "Flakes", nix.dev