Have you ever spent hours manually updating dependencies in your Cargo.toml? Copying version numbers from crates.io, wondering which updates are safe, and hoping nothing breaks?
Yeah, me too. That's why I built cargo-sane.
π€ The Problem
Managing Rust dependencies is tedious:
- You need to check crates.io for each dependency manually
- You don't know which updates are safe (patch? minor? major?)
- Version conflicts are confusing
- One wrong update can break your entire build
- There's no easy way to preview changes
There had to be a better way.
π‘ The Solution
I wanted a tool that would:
- β Automatically check all dependencies for updates
- β Categorize updates by risk level
- β Let me choose which ones to update
- β Make backups automatically
- β Preserve my carefully crafted Cargo.toml formatting
So I built cargo-sane.
π What It Does
Smart Dependency Analysis
cargo sane check
This scans your Cargo.toml, hits the crates.io API, and shows you exactly what's available:
π§ cargo-sane check
π Update Summary:
β
Up to date: 3
π’ Patch updates available: 5
π‘ Minor updates available: 2
π΄ Major updates available: 1
π’ Patch updates:
β’ serde 1.0.195 β 1.0.228
β’ anyhow 1.0.89 β 1.0.100
π‘ Minor updates:
β’ tokio 1.35.0 β 1.47.2
π΄ Major updates:
β’ colored 2.1.0 β 3.0.0
Color-coded by risk:
- π’ Green = Patch updates (bug fixes, likely safe)
- π‘ Yellow = Minor updates (new features, should be safe)
- π΄ Red = Major updates (breaking changes, be careful!)
Interactive Updates
cargo sane update
This opens a beautiful TUI where you can:
- Select which dependencies to update (spacebar to toggle)
- See exactly what will change
- Preview before applying
And it:
- Creates automatic backups (
Cargo.toml.backup) - Preserves your formatting and comments
- Works with all Cargo.toml formats
# Simple format
serde = "1.0"
# Detailed format with features
tokio = { version = "1.35", features = ["full"] }
# Optional dependencies
clap = { version = "4.5", optional = true }
# Comments are preserved!
regex = "1.11" # For pattern matching
π οΈ How I Built It
Tech Stack
- Language: Rust (obviously!)
- CLI Framework: clap for argument parsing
- HTTP Client: reqwest for crates.io API
- Version Parsing: semver
- TUI: dialoguer for interactive prompts
- Pretty Output: colored + indicatif
Key Challenges
1. Parsing Cargo.toml
Cargo.toml has many formats:
serde = "1.0"
tokio = { version = "1.35", features = ["full"] }
clap = { version = "4.5", optional = true }
I used the toml crate to parse, then created a custom Manifest struct to handle all variants.
2. Updating While Preserving Format
The tricky part: updating versions WITHOUT destroying formatting and comments.
Solution: Use regex to find and replace only the version string:
let pattern = format!(
r#"(?m)^(\s*{}\s*=\s*\{{\s*version\s*=\s*")([^"]+)(")"#,
regex::escape(dep_name)
);
let new_content = re.replace(&content, |caps: ®ex::Captures| {
format!("{}{}{}", &caps[1], new_version, &caps[3])
});
This preserves everything except the version number itself.
3. Concurrent API Calls
Checking 50+ dependencies one-by-one would be slow. Solution: concurrent requests with progress bars:
use indicatif::ProgressBar;
let pb = ProgressBar::new(deps.len() as u64);
for (name, spec) in deps {
pb.set_message(format!("Checking {}", name));
// Fetch from crates.io API
pb.inc(1);
}
π Results
After publishing to crates.io, the response has been amazing:
- Published just hours ago
- Already seeing downloads
- Great feedback on design and UX
- Ideas for new features flooding in
π― What's Next
Future features I'm planning:
- Conflict Resolution: Automatically fix version conflicts
- Security Scanning: RustSec integration for vulnerability checks
- Unused Dependencies: Detect and remove unused crates
- Workspace Support: Handle multi-crate workspaces
- CI/CD Integration: GitHub Actions support
π Try It Yourself
cargo install cargo-sane
cd your-rust-project
cargo sane check
cargo sane update
Links:
π Lessons Learned
Building cargo-sane taught me:
- Good UX matters in CLI tools - Color coding and progress bars make a huge difference
- Start simple - MVP first, then iterate based on feedback
- Preserve user data - Automatic backups = peace of mind
- Documentation is crucial - Good README = more users
- Community feedback is gold - Listen to your users
π€ Want to Contribute?
cargo-sane is open source! PRs welcome:
- π Found a bug? Open an issue
- π‘ Have an idea? Let's discuss it
- π§ Want to contribute? Fork and PR
What do you think? Would you use cargo-sane? What features would you want to see?
Drop a comment below! π

Top comments (0)