# Cargo Workspaces --- ## Cargo Workspaces Allow you to split your project into several packages * further encourages modularity * develop multiple applications and libraries in a single tree * synchronized dependency management, release process, etc. * a way to parallelize compilation and speed up builds * **your internal projects should likely be workspaces** even if you don't use monorepos --- ## Anatomy of Rust Workspace ```text my-app/ ├── Cargo.toml # a special workspace file ├── Cargo.lock # notice that Cargo produces a common lockfile for all packages ├── packages/ # can use any directory structure │ ├── main-app/ │ │ ├── Cargo.toml │ │ └── src/ │ │ └── main.rs │ ├── admin-app/ │ │ └── ... │ ├── common-data-model/ │ │ ├── Cargo.toml │ │ └── src/ │ │ └── lib.rs │ ├── useful-macros │ ├── service-a │ ├── service-b │ └── ... └── tools/ # packages don't have to be in the same directory ├── release-bot/ │ ├── Cargo.toml │ └── src/ │ └── main.rs ├── data-migration-scripts/ │ ├── Cargo.toml │ └── src/ │ └── main.rs └── ... ``` --- ## Workspace Cargo.toml ```toml [workspace] resolver = "2" members = ["packages/*", "tools/*"] [dependencies] thiserror = "1.0.39" ... ``` using wildcards for members is very handy when you want to add new member packages, split packages, etc. --- ## Cargo.toml for a workspace member ```toml [package] name = "main-app" [dependencies] thiserror = { workspace = true } service-a = { path = "../service-a" } ... ``` --- ## Cargo commands for workspaces * `cargo run --bin main-app` * `cargo test -p service-a` --- ## Creating a workspace ```sh #!/usr/bin/env bash function nw() { local name="$1" local work_dir="$PWD" mkdir -p "$work_dir/$name/packages" git init -q "$work_dir/$name" cat > "$work_dir/$name/Cargo.toml" << EOF [workspace] resolver = "2" members = ["packages/*"] [workspace.dependencies] EOF cat > "$work_dir/$name/.gitignore" << EOF target EOF code "$work_dir/$name" } ``` Example: ```bash nw spaceship cargo new --lib spaceship/packages/fuel-control ```