Architecture Overview

Fromager rebuilds complete dependency trees of Python wheels from source. This document maps the major subsystems and how they connect.

See also

Bootstrap vs Build explains the two operating modes. Bootstrapper Architecture details the bootstrap engine. Resolver Architecture covers version resolution. Hooks and Overrides describes the two plugin systems. Package Settings explains the settings layering.

Major Subsystems

┌───────────────────────────────────────────────────────┐
│                    CLI & Context                      │
│         command parsing, WorkContext, settings        │
└───────────────────────────┬───────────────────────────┘
                            │
                            ▼
┌───────────────────────────────────────────────────────┐
│                  Bootstrap Engine                     │
│        iterative DFS loop over phase pipeline         │
│                                                       │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│   │ Resolution  │  │    Source   │  │     Build   │   │
│   │ PyPI, graph │  │ Acquisition │  │   System    │   │
│   │  git URLs   │  │  download,  │  │  isolated   │   │
│   │             │  │ patch, Rust │  │   envs,     │   │
│   │             │  │   vendor    │  │   wheels    │   │
│   └─────────────┘  └─────────────┘  └─────────────┘   │
└───────────────────────────┬───────────────────────────┘
                            │
           ┌────────────────┴────────────────┐
           ▼                                 ▼
┌──────────────────┐              ┌──────────────────┐
│  Per-Package     │              │   Global Hooks   │
│  Overrides       │              │ post_bootstrap,  │
│                  │              │    post_build    │
└──────────────────┘              └──────────────────┘

The bootstrap engine orchestrates the other subsystems. For each package it resolves a version, downloads the source, builds a wheel, and recurses into dependencies. Resolution, source acquisition, and build are called as needed during each phase of the pipeline.

Extension points intercept the pipeline at specific steps, allowing per-package overrides (e.g. custom download logic) and global hooks (e.g. post-build notifications).

Data Flow

A fromager bootstrap invocation flows through the subsystems in this order:

requirements.txt
                            │
                            ▼
┌─ CLI & Context ───────────────────────────────────────┐
│  parse args, load settings, create WorkContext        │
└───────────────────────────┬───────────────────────────┘
                            │
                            ▼
┌─ Bootstrap Engine (iterative DFS) ────────────────────┐
│                                                       │
│  ┌─────────────┐   ┌─────────────┐                    │
│  │   Resolve   │──►│  Download   │                    │
│  │   version   │   │   source    │                    │
│  └─────────────┘   └──────┬──────┘                    │
│                           │                           │
│                           ▼                           │
│  ┌─────────────┐   ┌─────────────┐                    │
│  │  Extract &  │◄──│    Build    │                    │
│  │  recurse    │   │    wheel    │                    │
│  │  into deps  │   │             │                    │
│  └─────────────┘   └─────────────┘                    │
│                                                       │
└───────────────────────────┬───────────────────────────┘
                            │
                            ▼
                     ┌── Outputs ──┐
                     │ graph.json  │
                     │ build-order │
                     │ wheels/     │
                     │ constraints │
                     └─────────────┘

The build command uses the same source acquisition and build subsystems but skips resolution and recursion – it compiles a single package given a name, version, and source URL.

Extension Points

Fromager has two plugin systems:

System

Scope

When it fires

Per-package overrides

One package

At each pipeline step (download, build sdist, build wheel, dependency extraction, etc.)

Global hooks

All packages

After specific events (post_bootstrap, post_build, prebuilt_wheel)

Per-package overrides replace the default implementation of a step for a specific package. Global hooks run in addition to the default logic for every package. See Hooks and Overrides for the full breakdown.

Key Data Structures

Four data structures flow between subsystems:

Structure

Role

WorkContext

Central configuration and state: directory paths, constraints, dependency graph, settings, and variant info. Passed to every subsystem.

DependencyGraph

In-memory directed graph of all resolved dependencies. Serialized to graph.json. Thread-safe.

PackageBuildInfo

Per-package build configuration: environment variables, patches, resolver settings, and build options. Derived from settings files.

BuildEnvironment

Isolated virtual environment for building one package. Created per source build, cleaned up after completion.