How Fuel Core Implements a Monorepo Structure with Multiple Rust Crates

Fuel Core uses a Cargo workspace to coordinate dozens of interconnected Rust crates under a single repository, enabling atomic cross-crate changes with unified dependency management and incremental builds.

The FuelLabs/fuel-core repository demonstrates enterprise-grade monorepo architecture for blockchain infrastructure. By organizing the node implementation, cryptographic primitives, protocol definitions, and tooling as separate but interdependent crates, the project maintains clear separation of concerns while allowing developers to modify the entire stack in a single commit.

The Cargo Workspace Foundation

At the root of the repository, the Cargo.toml file declares a workspace that treats all member crates as part of a single build graph. This configuration pins shared dependencies in a [workspace.dependencies] table, ensuring that crates like tokio, serde, and anyhow resolve to identical versions across the entire codebase.

The workspace definition enumerates every crate in the members array, typically located under the crates/ directory. This structure allows the compiler to perform incremental builds—only recompiling crates that actually changed—while maintaining a single Cargo.lock file at the repository root.

Monorepo Directory Structure

Fuel Core organizes its codebase into logical partitions that separate library code from binaries and integration tests:


fuel-core/
├─ Cargo.toml                    # Workspace definition

├─ crates/
│   ├─ fuel-core/               # Main node implementation

│   ├─ fuel-cli/                # CLI wrapper

│   ├─ fuel-gql/                # GraphQL API server

│   ├─ fuel-crypto/             # Cryptographic primitives

│   ├─ fuel-protocol/           # Protocol encoding/decoding

│   ├─ fuel-storage/            # RocksDB storage layer

│   ├─ types/                   # Shared data structures

│   └─ keygen/                  # Key generation utilities

├─ bin/                         # Executable entry points

│   ├─ fuel-core/               # Node binary

│   └─ fuel-cli/                # CLI binary

├─ tests/                       # Cross-crate integration tests

├─ benches/                     # Performance benchmarks

└─ docs/                        # Documentation and diagrams

Source: [Root Cargo.toml](https://github.com/FuelLabs/fuel-core/blob/master/Cargo.toml)

Core Crate Responsibilities

Each directory under crates/ represents an独立 library with a specific domain responsibility.

fuel-core

The crates/fuel-core/ directory contains the primary node implementation, exposing the NodeService struct and core consensus logic. This crate serves as the central dependency for other tools that need to programmatically start or interact with a Fuel node.

fuel-cli

Located at crates/fuel-cli/, this crate provides a command-line interface that wraps the core node functionality. It demonstrates how client tools consume the node library through local path dependencies rather than published crate versions.

fuel-gql

The GraphQL API server lives in crates/fuel-gql/, exposing blockchain data queries through an async server interface that integrates directly with the storage and protocol crates.

fuel-storage

This crate implements the persistence layer, including RocksDB backends. The Cargo.toml defines optional feature flags like "rocksdb" that conditionally compile storage backends:

[features]
rocksdb = ["dep:rocksdb"]

Source: [fuel-storage Cargo.toml](https://github.com/FuelLabs/fuel-core/blob/master/crates/fuel-storage/Cargo.toml)

Cross-Crate Dependencies and Path References

Crates reference siblings using path dependencies rather than version requirements. This enables immediate propagation of changes without publishing intermediate crates to crates.io.

For example, fuel-cli declares its dependency on the core node library in crates/fuel-cli/Cargo.toml:

[dependencies]
fuel-core = { path = "../fuel-core" }

Source: [fuel-cli Cargo.toml](https://github.com/FuelLabs/fuel-core/blob/master/crates/fuel-cli/Cargo.toml)

Similarly, binaries in the bin/ directory act as thin wrappers that depend on library crates. The bin/fuel-core/Cargo.toml specifies:

[dependencies]
fuel-core = { path = "../../crates/fuel-core" }

Source: bin/fuel-core/Cargo.toml

Integration Testing Across the Workspace

The top-level tests/ directory contains integration tests that import multiple crates simultaneously. Because all crates share the same workspace, tests can spin up complete node instances and exercise the full stack without publishing dependencies.

For instance, tests/tests/tx.rs validates transaction processing by importing types from fuel-core and fuel-protocol directly, enabling end-to-end verification that unit tests within individual crates cannot provide.

Source: tests/tests/tx.rs

Building and Developing in the Monorepo

To compile the entire workspace with all optional features enabled:

cargo build --workspace --all-features

To run a specific binary, navigate to its directory or use the package flag:


# Build the node binary specifically

cargo run -p fuel-core-bin --release

# Or from the bin directory

cd bin/fuel-core
cargo run --release

When adding new functionality that spans multiple crates, developers can modify fuel-protocol and immediately test the changes in fuel-core without version bumps or registry updates. To add a new crate to the workspace:

  1. Create the crate: cargo new --lib crates/my-tool
  2. Add path dependencies to sibling crates as needed
  3. Register the crate in the root Cargo.toml members array:
[workspace]
members = [
    "crates/fuel-core",
    "crates/my-tool",
    # ... other crates

]

Summary

  • Cargo workspace architecture: The root Cargo.toml defines a unified build graph with shared dependency versions across all crates.
  • Path-based dependencies: Crates reference each other via path = "../crate-name", enabling instantaneous cross-crate refactoring without publishing cycles.
  • Clear separation of concerns: fuel-core handles consensus, fuel-storage manages persistence, fuel-gql serves APIs, and fuel-cli provides user interfaces.
  • Comprehensive integration testing: The tests/ directory exercises the full node stack by importing multiple workspace crates in a single test suite.
  • Feature flag coordination: Optional dependencies like RocksDB are toggled at the workspace level, allowing CI to validate multiple configuration matrices.

Frequently Asked Questions

How does Fuel Core manage dependencies across its monorepo crates?

Fuel Core uses the [workspace.dependencies] table in the root Cargo.toml to pin versions of common libraries like tokio and serde. All member crates inherit these versions, preventing diamond dependency conflicts and ensuring that every crate compiles against identical dependency versions.

Why does Fuel Core use path dependencies instead of publishing internal crates?

Path dependencies allow developers to modify fuel-protocol or fuel-crypto and immediately test those changes in fuel-core without waiting for crates.io publishes or version bumps. This supports atomic commits that refactor APIs across multiple crates simultaneously.

Where are executable binaries defined in the Fuel Core monorepo?

Binaries reside in the bin/ directory, with each subdirectory containing a Cargo.toml that declares a [[bin]] target depending on library crates via path references. For example, bin/fuel-core/Cargo.toml wraps the crates/fuel-core library into the final node executable.

How do I enable optional features when building Fuel Core?

Use the --features flag with the specific package. For example, to build the node with RocksDB storage support:

cargo build -p fuel-core --features rocksdb

The workspace coordinates feature flags so that enabling a feature in the root or a specific crate propagates correctly through the dependency graph.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →