January 28, 2026·6 min read·engineeringnixbootstrapsecurity

A source bootstrap extends NixOS beyond its initial binary tools

A NixOS bootstrap proof of concept connects a source-built package environment to a source-built Nix. It addresses the compiler ancestry that remains outside an ordinary declarative system configuration.

A declarative system can describe every package it wants while still relying on a compiler binary whose ancestry it has not established. That is the problem behind the full-source NixOS bootstrap announced on January 28. The project connects an Aux Foundation-based Nixpkgs bootstrap with a live-bootstrap-based process that builds Nix itself. Its author presents the work as a proof of concept for further upstream development.

The result matters because the package manager also needs a construction history. Replacing prebuilt compiler tools inside Nixpkgs answers one question. Building the Nix executable that evaluates and realizes the package set answers another. A complete account has to connect both, or it leaves a substantial executable outside the chain it claims to explain.

Nix and NixOS manage the desired state of my personal infrastructure. Four years with them have made declarative reconstruction central to how I think about operating systems. The bootstrap project interests me because it asks what the reconstruction starts from. Declaring an input makes the dependency explicit, but it does not by itself explain how that input came to exist.

Two bootstrap chains have different jobs

The project repository describes an inner bootstrap and an outer bootstrap. The inner part modifies a Nixpkgs fork to replace its usual prebuilt bootstrap seeds with tools built through Aux Foundation. Outside it, the project extends live-bootstrap to construct a NixOS installation using that modified package set.

That division follows a real dependency boundary. Nixpkgs contains package definitions that Nix evaluates. Nix is also an executable with a compiler and library history of its own. A source-built package collection still needs something capable of interpreting the collection and running its build operations. The outer process supplies that missing part before the combined system can build itself further.

The repository links the two component forks through submodules. This gives the proof of concept identifiable implementations for both parts. It also means the top-level project is more than an alternative NixOS configuration file. Its result depends on modified construction procedures in the package set and the surrounding bootstrap environment.

The author credits Jake Hamilton and Emily Trau for the Aux Foundation work on which the inner chain depends. That is a useful reminder about the scale of the result. The new contribution joins existing bootstrap efforts and extends them into a system installation. It does not claim that one thesis independently implemented every early compiler and utility in the chain.

The standard environment already has staged ancestry

The Linux standard-environment source in the project fork explains its existing bootstrap goals. The final environment must neither reference nor contain the bootstrap files, and it must avoid retaining files directly produced by bootstrap code generators. Those constraints concern what remains in the final environment after successive rebuilding stages.

The code constructs stages that gradually rebuild the compiler and supporting tools. Its comments distinguish the compiler used to generate code from the compiler that will remain in the final environment. An intermediate compiler can be useful without becoming part of the final package set. That distinction explains why a bootstrap is a sequence of environments instead of one invocation of a modern compiler.

The implementation also tracks whether packages originate from bootstrap files and whether their compiler does. Assertions make those relationships explicit between stages. This provides a concrete way to express construction requirements in code. A package dependency graph can then distinguish an intended transition from an accidental surviving reference to an early tool.

Replacing the initial binary tools changes the beginning of that sequence. It does not remove the need for the later stages or their consistency rules. A smaller initial trust requirement still has to produce tools that can build the standard environment expected by ordinary package definitions. The existing staging logic remains relevant after the initial source bootstrap succeeds.

This is one reason the proof of concept belongs in package construction work. A system-level option cannot supply all the missing compiler transitions merely by describing a desired final package list. The package definitions and build environments need to encode how earlier tools can produce later ones.

Compiler ancestry is different from source availability

The thesis frames the work around the trust placed in self-hosting compilers. It constructs an environment from a small auditable seed and connects that environment to a NixOS installation. The result still has limits, including compiler families the project cannot yet bootstrap from its seed.

That qualification prevents an overly broad claim about the package collection. A demonstrated route to a working operating-system installation does not establish a source bootstrap for every optional compiler and package that could be added later. The scope of the construction needs to accompany the result. Otherwise, a user could introduce a binary seed through another package while believing the original property remained unchanged.

Source availability and reproducibility also answer different questions. Public source permits inspection of the program description. Repeating a build can establish agreement between results under specified conditions. A bootstrap chain explains how executable tools were obtained before those builds. The evidence is strongest when those relationships are documented separately and then connected.

My preference for Nix is grounded in making dependencies explicit enough to reconstruct a system. This work applies that preference further down the construction process. It turns part of the compiler ancestry into package-building work that can be inspected, instead of treating an opaque initial archive as the end of the explanation.

The outer environment introduces practical constraints

The project documentation describes a Linux preparation environment and an x86-64 target. It provides separate QEMU and physical-machine routes. The physical route requires BIOS boot support, and the source preparation has an offline mode. These are properties of this proof of concept, not a claim that every NixOS machine can adopt the process unchanged.

Those constraints matter to the meaning of a successful demonstration. A construction that works for one architecture can establish an end-to-end path without providing equivalent paths for every architecture supported by the wider package collection. Extending the result requires work on the early tools and platform transitions, not merely changing the final system identifier.

The project also provides backup source information. A long bootstrap depends on historical source releases remaining obtainable. Describing a dependency by URL does not keep the server available. Preserving source artifacts is therefore part of maintaining the construction, particularly when early compiler stages need versions that ordinary application users no longer install.

Offline preparation changes the operational question again. The build needs the complete required inputs before it can proceed without network access. A dependency description that still fetches material implicitly would leave part of the preparation incomplete. The project treats that as an implementation problem to solve alongside compiler construction.

The announcement says the fork is not ready to merge into Nixpkgs as it stands. A same-day reply points to Nixpkgs pull request 479322, which connects minimal-bootstrap to the standard environment. That is relevant parallel work, but it should not be confused with a claim that the entire thesis implementation has become the default upstream installation path.

The two efforts provide material for comparison. One demonstrates a combined route through Nix itself into an installed system. The other concerns the integration boundary inside the package set. Their overlap can reduce duplicated work while leaving different surrounding responsibilities to resolve. The announcement explicitly invites further development instead of presenting the fork as a finished distribution replacement.

For everyday operators, the immediate value is a clearer account of what declarative reconstruction does and does not establish. A configuration can remain useful while its compiler seed is still trusted as an external binary. This proof of concept shows a way to reduce that assumption for a defined construction. Extending it into maintained package infrastructure requires preserving the chain as its component tools and package definitions change.

The maintenance problem includes keeping the bootstrap route connected to ordinary package work. A construction that only works against one frozen fork has a different operational role from a route continuously exercised by package maintainers. The published code and thesis now give that integration work a concrete starting point, including the distinction between bootstrapping the package environment and bootstrapping the manager that builds it.