This repository provides a centralized management system for Rust crate dependencies using Bazel's crate_universe.
The SCORE Crates repository implements a streamlined approach for Rust crate dependencies that:
- Defines crates directly in
MODULE.bazel
usingcrate.spec()
- Uses rules_rust crate_universe for dependency resolution
- Provides convenient aliases via auto-generated BUILD file
- Automatically syncs aliases with
@crate_index
targets
When multiple Bazel modules depend on each other and both pull in Rust crates via rules_rust, Bazel pulls in the same crate multiple times. This leads to name clashes in the Rust compiler, even when using identical versions.
Module A Module B
├── crate.spec(serde) ├── crate.spec(serde)
└── @crate_index_a//:serde └── @crate_index_b//:serde
↘ ↙
Your Application
(💥 Name clash: two different serde crates!)
SCORE Crates Module
├── crate.spec(serde)
└── @crate_index//:serde
↙ ↘
Module A Module B
(uses SCORE) (uses SCORE)
↘ ↙
Your Application
(✅ Single serde crate!)
- Eliminates duplicate crates: Only one instance of each crate version across the entire workspace
- Prevents name clashes: Rust compiler sees consistent crate definitions
- Simplifies dependency management: Single source of truth for all crate versions
- Reduces build times: No duplicate compilation of the same crates
- Ensures consistency: All modules use identical crate versions and features
score-crates/
├── BUILD # Auto-generated aliases from @crate_index
├── MODULE.bazel # Bazel module with crate specifications
├── update_BUILD_file.sh # Script to sync BUILD with @crate_index
└── README.md # This file
The single source of truth for crate definitions using crate.spec()
:
module(name = "score-crates")
bazel_dep(name = "rules_rust", version = "0.61.0")
crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
crate.spec(
package = "clap",
version = "4.5.4",
features = ["derive"],
)
crate.spec(
package = "futures",
version = "0.3.31",
)
# Add more crate.spec() calls here...
crate.from_specs(name = "crate_index")
use_repo(crate, "crate_index")
Contains auto-generated aliases pointing to @crate_index
targets:
alias(
name = "clap",
actual = "@crate_index//:clap",
visibility = ["//visibility:public"],
)
The update_BUILD_file.sh
script automatically generates aliases for all crates found in @crate_index
.
- Add as a dependency in your
MODULE.bazel
:
bazel_dep(name = "score-crates", version = "1.0.0")
- Use crates in your BUILD files:
load("@rules_rust//rust:defs.bzl", "rust_binary")
rust_binary(
name = "my_app",
srcs = ["main.rs"],
deps = [
"@score-crates//:clap", # Via local aliases
"@score-crates//:futures", # Via local aliases
],
)
- Edit MODULE.bazel - Add a new
crate.spec()
call:
crate.spec(
package = "tokio",
version = "1.40.0",
features = ["full"],
)
- Update aliases - Run the sync script:
./update_BUILD_file.sh
- The crate will be available as:
@score-crates//:tokio
(via local alias)