Architecture
How the crates are layered — from the shared common/EVM cores up to the four user-facing binaries.
Third-party documentation. This is independently authored analysis of the public Foundry codebase — not the official docs, and not reviewed or endorsed by the Foundry team.
Architecture
Foundry is a Rust workspace whose crates layer cleanly: the four binaries users invoke are thin frontends over shared cores, which is why a feature added once (say, trace decoding) shows up identically in Forge test output, Cast output, and Anvil logs.
The crate layers
- foundry-common — shared types: chain specs, ABI utilities, contract artifacts, and RPC client helpers used by every tool.
- foundry-compilers — the Solidity build pipeline: solc version management, import graph resolution, incremental caching keyed on source hashes, and artifact emission.
- foundry-evm — the execution core. It wraps an EVM implementation and layers Foundry's own semantics on top: cheatcode interception, state forking, fuzz-case generation, coverage collection, and call tracing.
- forge / cast / anvil binaries — argument parsing, user output, and orchestration. Forge drives the compilers plus foundry-evm to run tests; Anvil wraps the same EVM in a JSON-RPC server speaking the full node API surface; Cast is largely stateless, formatting calls into and results out of any endpoint.
How a test actually runs
A forge test invocation compiles changed sources, deploys each test contract into a fresh in-memory EVM instance, runs setUp(), then executes each test* function. Special calls to the cheatcode address are intercepted before execution and answered by the host — that is how time travel, prank impersonation, and mock calls work without touching real opcodes. Failures capture full call traces and revert data, which the binary then pretty-prints with decoded ABI frames.
Forking
When configured with a remote RPC URL, foundry-evm lazily proxies storage reads and account lookups to the live network through Anvil's fork backend, caching responses locally. Tests therefore execute at native speed while reading real mainnet state — the boundary between local and remote state is maintained per-access.
System Diagram
Forge, Anvil, and Cast share a fast local EVM and Solidity toolchain.
