Zero-waste orchestration for Rust monorepos.
Stop wasting CI time. Stop fighting workspace dependencies. Stop copy-pasting git history.
cargo install cargo-railcargo-rail solves the three hardest problems in Rust monorepos:
| Problem | Solution | Impact |
|---|---|---|
| 🔥 Testing everything on every PR | Graph-aware change detection | 10x faster CI |
| 💥 Dependency fragmentation | Resolution-based unification | Zero workspace-hack crates |
| 🔨 Distributing crates | History-preserving split/sync | One command, full git history |
# Only test what changed
cargo rail test
# Explain why each crate is tested
cargo rail test --explainBefore:
- run: cargo test --workspace # Tests everything (12 minutes)After:
- run: cargo rail test --nextest # Tests only affected crates (1 minute)# Preview unification changes
cargo rail unify --dry-run
# Apply unification to workspace.dependencies
cargo rail unifyWhat it does:
- Uses Cargo's actual dependency resolution, not just syntax
- Merges feature sets intelligently from resolved features
- No workspace-hack crate needed
- Lossless TOML editing (preserves comments & formatting)
# Split a crate to standalone repo with full git history
cargo rail split my-crate
# Bidirectional sync
cargo rail sync my-crateWhat it does:
- Preserves complete git history (commits, tags, blame)
- Deterministic: same input = same commit SHAs
- Uses git-notes for rebase-safe commit mapping
- No libgit2/gitoxide dependency (pure system git)
Unlike cargo-hakari's syntax-only approach, cargo-rail uses Cargo's actual resolver:
# crate-a
tokio = "1.0"
# crate-b
tokio = "^1.5"
# Both resolve to tokio 1.5.3 → compatible!
# cargo-rail merges them intelligently:
[workspace.dependencies]
tokio = { version = "1.5", features = ["rt", "net", "sync"] }No workspace-hack crate. Just native workspace.dependencies.
$ cargo rail affected --explain
Changed files:
crates/core/src/lib.rs (source)
docs/guide.md (docs)
Affected crates:
✓ core (direct change)
✓ api (depends on core)
✓ cli (depends on api)
Skipping:
✗ examples (no dependency path)
✗ docs (docs-only change)
Running: cargo nextest run -p core -p api -p cliReal impact: 70-90% reduction in test time on large workspaces.
Uses system git directly for maximum fidelity:
# Split preserves full history
git log --oneline
abc123 feat: add new feature
def456 fix: critical bug
...
# Same commits, same SHAs in split repo
cd ../my-crate-standalone
git log --oneline
abc123 feat: add new feature # Same SHA!
def456 fix: critical bug # Same SHA!- System git only – No libgit2/gitoxide dependency overhead
- Direct graph construction –
cargo_metadata+petgraph(no guppy) - 8 core dependencies – Minimal, auditable supply chain
- Single workspace load – Build context once, reuse everywhere
- Graph-first – All operations use the dependency graph
- Lossless editing – Preserve formatting, comments, structure
- Deterministic – Same input always produces same output
Create .config/rail.toml:
# Toolchain management
[toolchain]
channel = "stable"
components = ["clippy", "rustfmt"]
# Dependency unification
[unify]
consolidate_transitive_features = false # Consolidate transitive deps
transitive_feature_host = "auto" # Smart auto-selection
validate_targets = []
# Split/sync (optional)
[[splits]]
name = "my-crate"
remote = "[email protected]:org/my-crate.git"
mode = "single"See .config/rail.toml.example for all options.
cargo rail affected # Show affected crates
cargo rail affected --since main # Compare against branch
cargo rail test # Test affected crates
cargo rail test --nextest --watch # Watch mode with nextestcargo rail unify --dry-run # Preview changes
cargo rail unify # Apply unificationcargo rail split my-crate # Split to standalone repo
cargo rail sync my-crate # Bidirectional sync
cargo rail status # Show sync statuscargo rail release plan --all # Plan release
cargo rail release publish --execute # Publish to crates.io| Feature | cargo-rail | cargo-hakari | Copybara |
|---|---|---|---|
| Dependency unification | ✅ Resolution-based | ✅ Syntax-only | ❌ |
| Workspace-hack crate | ❌ Not needed | ✅ Required | ❌ |
| Git history preservation | ✅ Full | ❌ | |
| Bidirectional sync | ✅ | ❌ | ✅ |
| Deterministic | ✅ Same SHAs | N/A | ❌ |
| Smart testing | ✅ Graph-aware | ❌ | ❌ |
| Dependencies | 8 core | ~40+ (via guppy) | Go ecosystem |
# CI takes 12 minutes testing entire workspace
# Maintain workspace-hack crate manually
# Use git-filter-repo scripts for splits# CI takes 1-2 minutes testing only affected crates
# cargo rail unify (one command)
# cargo rail split my-crate (one command, full history)# From crates.io
cargo install cargo-rail
# From source
git clone https://github.com/loadingalias/cargo-rail
cd cargo-rail
cargo install --path .# Build
cargo build --release
# Test
cargo test
# Quality checks
just checkContributions welcome! Please:
- Open an issue first for major changes
- Run
just checkbefore submitting - Add tests for new features
- Update docs as needed
MIT License - see LICENSE for details.
Built with cargo_metadata, petgraph, toml_edit, and clap.
Inspired by cargo-hakari's unification approach and Copybara's monorepo concepts.
Ready to stop wasting time? cargo install cargo-rail