# How Fuel Core Implements a Monorepo Structure with Multiple Rust Crates

> Discover how Fuel Core leverages Rust crates within a monorepo structure. Learn about its Cargo workspace, unified dependency management, and atomic cross-crate changes for efficient development.

- Repository: [Fuel Labs/fuel-core](https://github.com/FuelLabs/fuel-core)
- Tags: internals
- Published: 2026-03-06

---

**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`](https://github.com/FuelLabs/fuel-core/blob/main/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/main/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`](https://github.com/FuelLabs/fuel-core/blob/main/Cargo.toml) defines optional feature flags like `"rocksdb"` that conditionally compile storage backends:

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

```

*Source*: [fuel-storage [`Cargo.toml`](https://github.com/FuelLabs/fuel-core/blob/main/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`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-cli/Cargo.toml):

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

```

*Source*: [fuel-cli [`Cargo.toml`](https://github.com/FuelLabs/fuel-core/blob/main/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`](https://github.com/FuelLabs/fuel-core/blob/main/bin/fuel-core/Cargo.toml) specifies:

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

```

*Source*: [bin/fuel-core/Cargo.toml](https://github.com/FuelLabs/fuel-core/blob/master/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`](https://github.com/FuelLabs/fuel-core/blob/main/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](https://github.com/FuelLabs/fuel-core/blob/master/tests/tests/tx.rs)

## Building and Developing in the Monorepo

To compile the entire workspace with all optional features enabled:

```bash
cargo build --workspace --all-features

```

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

```bash

# 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`](https://github.com/FuelLabs/fuel-core/blob/main/Cargo.toml) members array:

```toml
[workspace]
members = [
    "crates/fuel-core",
    "crates/my-tool",
    # ... other crates

]

```

## Summary

- **Cargo workspace architecture**: The root [`Cargo.toml`](https://github.com/FuelLabs/fuel-core/blob/main/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`](https://github.com/FuelLabs/fuel-core/blob/main/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`](https://github.com/FuelLabs/fuel-core/blob/main/Cargo.toml) that declares a `[[bin]]` target depending on library crates via path references. For example, [`bin/fuel-core/Cargo.toml`](https://github.com/FuelLabs/fuel-core/blob/main/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:

```bash
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.