Crate Dependency Graph
The base/base workspace organizes 8 top-level crate groups into a directed acyclic dependency graph. This page traces how the groups connect, which crates are foundational, and where the integration boundaries sit.
High-level dependency flow
Section titled “High-level dependency flow”The dependency graph flows downward: higher-level groups depend on lower-level ones, but not the reverse.
┌─────────────────────────────────────────────────────┐│ infra ││ based, basectl, ingress-rpc, websocket-proxy, ... │└───────────┬──────────┬──────────┬───────────────────┘ │ │ │ v v v┌──────────────┐ ┌──────────┐ ┌──────────┐│ builder │ │ client │ │consensus ││ core, pub, │ │ node,cli,│ │ protocol,││ metering │ │ engine, │ │ rpc,kona ││ │ │ flash │ │ │└──────┬───────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ ┌────┘ │ │ v │ │ ┌──────────┐ │ └───►│execution │◄──────────┘ └────┬─────┘ │ v ┌──────────┐ ┌──────────┐ │ shared │◄────│ proof │ └────┬─────┘ └──────────┘ │ v ┌──────────┐ │ alloy │ └──────────┘Key observations:
alloyandsharedsit at the bottom of the graph. They have no internal workspace dependencies and are consumed by everything above them.executiondepends onsharedandalloyfor types, and is consumed by bothclientandbuilder.clientis the main integration point — it pulls in execution, consensus, and shared.infrabinaries sit at the top, assembling components from multiple groups.proofis relatively isolated. It depends onsharedfor types but has its own Kona-derived execution and derivation logic (designed to run inside a fault proof VM).
Detailed crate-level dependencies
Section titled “Detailed crate-level dependencies”Alloy crates
Section titled “Alloy crates”alloy/ └── (external: alloy-rs ecosystem) No internal workspace dependencies. Consumed by: shared, client, consensus, builder, executionThe alloy crates define Ethereum and Optimism wire types using the Alloy framework. They are leaf dependencies with no intra-workspace imports.
Shared crates
Section titled “Shared crates”shared/ ├── base-primitives ← foundational types (blocks, txs, receipts) ├── base-bundles ← depends on: base-primitives ├── base-jwt ← standalone (JWT auth tokens) ├── base-cli-utils ← standalone (CLI helpers) ├── base-engine-ext ← depends on: base-primitives ├── base-access-lists ← depends on: base-primitives ├── base-reth-rpc-types ← depends on: base-primitives └── base-txpool-rpc ← depends on: base-primitives, base-reth-rpc-typesbase-primitives is the single most depended-upon crate. It defines BaseTxEnvelope, BaseBlock, chain IDs, and fee calculation types. Almost every other workspace crate imports it directly or transitively.
Execution crates
Section titled “Execution crates”execution/ └── (execution crates) depends on: base-primitives, alloy types consumed by: client, builderThe execution group provides Base’s EVM configuration. It depends on base-primitives for block and transaction types and on alloy types for encoding. The client and builder groups both consume execution crates to run EVM state transitions.
Consensus crates
Section titled “Consensus crates”consensus/ ├── base-protocol ← depends on: base-primitives ├── base-consensus-rpc ← depends on: base-protocol, base-primitives │ └── kona-* (vendored) ├── kona-node-service ← top-level; depends on most kona-* below ├── kona-engine ← depends on: kona-derive, kona-providers-alloy ├── kona-derive ← depends on: kona-sources, kona-genesis, kona-hardforks ├── kona-gossip ← depends on: kona-disc, kona-peers ├── kona-sources ← depends on: kona-providers-alloy ├── kona-providers-alloy ← depends on: kona-genesis ├── kona-genesis ← depends on: kona-registry ├── kona-registry ← depends on: kona-hardforks ├── kona-hardforks ← leaf ├── kona-disc ← leaf (peer discovery) ├── kona-peers ← leaf (peer management) ├── kona-cli ← leaf (CLI utils) └── kona-macros ← leaf (proc macros)The Kona crates form their own internal dependency tree. kona-node-service is the top-level entry point, and kona-derive is the core derivation pipeline. The Base-native consensus crates (base-protocol, base-consensus-rpc) integrate with the Kona stack and provide Base-specific protocol constants.
Builder crates
Section titled “Builder crates”builder/ ├── base-builder-core ← depends on: base-primitives, base-bundles, │ execution crates, base-engine-ext ├── base-builder-publish ← depends on: base-builder-core, base-primitives └── base-builder-metering ← depends on: base-builder-coreThe builder’s dependency chain:
base-builder-metering ──► base-builder-core ──► base-primitives │ │base-builder-publish ───────────┘ v alloy types │ v execution cratesbase-builder-core contains the block building loop and depends on execution crates for EVM access and on base-primitives for block/transaction types. base-builder-publish handles the output side — streaming flashblocks and submitting sealed blocks.
Client crates
Section titled “Client crates”client/ ├── base-client-node ← depends on: base-client-cli, base-client-engine, │ base-flashblocks, base-metering, base-txpool-tracing, │ execution crates, consensus crates, shared crates ├── base-client-cli ← depends on: base-cli-utils ├── base-client-engine ← depends on: base-primitives, base-engine-ext ├── base-flashblocks ← depends on: base-primitives ├── base-metering ← depends on: base-primitives, base-reth-rpc-types └── base-txpool-tracing ← depends on: base-primitivesbase-client-node is the integration hub. It is where Reth’s NodeBuilder is configured with all Base-specific components. Its dependency list is the longest in the workspace because it wires together execution, consensus, flashblocks, metering, and the transaction pool.
Proof crates
Section titled “Proof crates”proof/ ├── kona-proof ← depends on: kona-driver, kona-mpt ├── kona-driver ← depends on: kona-executor, kona-preimage ├── kona-executor ← depends on: kona-mpt, kona-preimage ├── kona-mpt ← leaf (Merkle Patricia Trie) ├── kona-preimage ← leaf (preimage oracle interface) ├── kona-std-fpvm ← leaf (FPVM runtime) └── kona-std-fpvm-proc ← leaf (proc macros for FPVM)The proof group is intentionally isolated from the rest of the workspace. It must be compilable to FPVM targets (MIPS/RISC-V), so it avoids pulling in networking, RPC, or OS-specific dependencies. It re-implements derivation and execution logic using kona-preimage to read data from the host environment.
Infra crates
Section titled “Infra crates”infra/ ├── based ← depends on: client, builder, consensus, shared ├── basectl-cli ← depends on: shared (base-cli-utils, base-primitives) ├── ingress-rpc-lib ← depends on: shared (base-jwt, base-primitives) ├── websocket-proxy ← depends on: shared (base-primitives) ├── mempool-rebroadcaster ← depends on: shared (base-primitives, base-txpool-rpc) ├── audit-archiver-lib ← depends on: shared (base-primitives) └── system-tests ← depends on: client, shared, infra binariesInfra crates are consumers. They import from the lower layers but are not imported by any other workspace crate (except system-tests, which depends on infra binaries for integration testing).
Dependency rules
Section titled “Dependency rules”The workspace follows these conventions:
- No circular dependencies. The crate graph is a DAG.
- Shared and alloy are leaf layers. They never depend on higher-level groups.
- Proof is sandboxed. Proof crates do not depend on client, builder, or infra crates, keeping them FPVM-compilable.
- External Reth dependencies flow through execution and client. Other groups do not directly import
reth-*crates; they go through the abstractions in execution or shared. - Kona crates are vendored, not patched. The consensus and proof groups contain full copies of Kona crates (not Git patches), allowing Base-specific modifications while preserving the ability to pull upstream changes.
Workspace Cargo.toml structure
Section titled “Workspace Cargo.toml structure”All inter-crate dependencies are declared as workspace dependencies in the root Cargo.toml. Individual crate Cargo.toml files reference these with workspace = true:
# Root Cargo.toml (excerpt)[workspace.dependencies]base-primitives = { path = "crates/shared/primitives" }base-builder-core = { path = "crates/builder/core" }base-client-node = { path = "crates/shared/node" }# ... etc.This centralized dependency management ensures version consistency and makes it straightforward to audit the full dependency graph.