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)