Skip to main content

Workspaces

A workspace is a way to group multiple related crates (binary and/or library) into one logical project.

Key idea:

A workspace lets multiple crates share the same Cargo.lock, target directory, and dependency versions.

So instead of one big crate, you build many small crates that work together.

Why Workspaces Exist (Real Reason)

Without workspaces, large projects become:

  • tightly coupled
  • hard to test independently
  • slow to compile
  • messy to reuse

Workspaces solve this by:

  • separating concerns into crates
  • allowing parallel compilation
  • enabling clean boundaries
  • sharing dependencies efficiently

What a Workspace Is NOT

  • A workspace is not a crate
  • A workspace has no code itself
  • A workspace does not compile to a binary or library

It is just an organizational layer.

Basic Workspace Structure

my_workspace/
├── Cargo.toml // workspace manifest
├── Cargo.lock
├── target/
├── app/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
└── core/
├── Cargo.toml
└── src/
└── lib.rs
  • app → binary crate
  • core → library crate

Workspace Cargo.toml

Root Cargo.toml

[workspace]
members = [
"app",
"core"
]
  • This file defines the workspace
  • No [package] section
  • Only workspace configuration

Library Crate Inside Workspace

core/Cargo.toml

[package]
name = "core"
version = "0.1.0"
edition = "2021"

core/src/lib.rs

pub fn add(a: i32, b: i32) -> i32 {
a + b
}

Binary Crate Using Workspace Library

app/Cargo.toml

[package]
name = "app"
version = "0.1.0"
edition = "2021"

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

app/src/main.rs

use core::add;

fn main() {
println!("{}", add(3, 4));
}
  • core is imported like a normal crate
  • path points to workspace member
  • No publishing required

Shared Cargo.lock and target/

In a workspace:

  • all crates share one Cargo.lock
  • all compiled artifacts go to one target/

Benefits:

  • consistent dependency versions
  • faster builds
  • less disk usage

Running & Building in a Workspace

Build everything

cargo build

Run a specific binary

cargo run -p app

Test one crate

cargo test -p core

Workspace with Multiple Binaries

my_workspace/
├── Cargo.toml
├── api/
├── cli/
└── shared/
  • api → backend service
  • cli → command-line tool
  • shared → common logic

All depend on shared.

Workspaces + Modules (How They Differ)

ConceptPurpose
ModuleOrganize code inside a crate
CrateCompilation unit
WorkspaceOrganize multiple crates

Rule of thumb:

  • small separation → module
  • strong boundary → crate
  • multiple apps/libs → workspace

When Should You Create a Workspace?

Use a workspace when:

  • you have multiple binaries
  • you want shared libraries
  • compile time is growing
  • you plan to publish some crates
  • different teams own different parts

Real-World Example (Production Style)

ecommerce/
├── Cargo.toml
├── auth/
├── payments/
├── inventory/
├── web/
└── common/
  • web → frontend server (binary)
  • auth, payments, inventory → services
  • common → shared types & utilities

Each crate:

  • has its own lib.rs or main.rs
  • its own dependencies
  • clear API boundaries

Workspace Dependency Inheritance (Advanced)

Root Cargo.toml

[workspace.dependencies]
serde = "1.0"

Member crate

[dependencies]
serde = { workspace = true }

This ensures:

  • same version everywhere
  • no duplication
  • easy upgrades

Publishing from a Workspace

You can:

  • publish individual crates
  • keep others private
  • share internal crates via path
  • Workspace does not affect publishing.

Common Workspace Mistakes

  • Putting code in root
  • One crate with too many responsibilities
  • Circular dependencies between crates
  • Making everything a workspace too early

Best Practices

  • Start with one crate
  • Extract crates when boundaries appear
  • Keep crates small and focused
  • Use pub(crate) for internal APIs
  • Re-export clean APIs from libraries

Mental Model (Very Important)

Think of Rust structure like this:

Workspace
└── Crates
└── Modules
└── Items

Each layer has a clear responsibility.