When you start working with Rust, you’ll quickly learn that cargo is your best friend. It gets your project started, downloads libraries, and builds your code. But as your project grows, or as you start thinking about sharing it with the world, you realize that cargo is just the beginning. There’s a whole collection of tools built around it that handle the messy, complicated, but absolutely essential jobs of versioning, securing, shrinking, and shipping your software.
Think of these tools as specialized assistants. cargo is your reliable general contractor, but these assistants are the electricians, plumbers, and architects who make sure the final house is safe, efficient, and ready for someone to live in. I remember hitting these pain points myself—accidentally publishing the wrong files, waiting forever for tools to compile, or having a final binary that was inexplicably huge. That’s when I went looking for help. Let’s talk about the helpers that changed my workflow.
First, let’s talk about releasing new versions. Manually updating version numbers in Cargo.toml, writing a changelog, creating a git tag, and pushing to crates.io is tedious and error-prone. Forget one step, and you have a mess. This is where cargo-release comes in. It automates the entire sequence.
You configure what you want to happen in your Cargo.toml. For instance, you can tell it to run your test suite before anything else, ensuring you don’t release broken code. You can define how your git tags should look.
[package.metadata.release]
pre-release-commands = ["cargo test"]
tag-name = "v{{version}}"
Using it is straightforward. You can do a dry run first, which is a safety net I use every single time. It shows you exactly what will change without actually changing anything.
cargo release patch --dry-run
When you’re satisfied, a single command handles the bump from, say, 1.0.0 to 1.0.1, updates files, creates the tag, pushes it, and publishes the crate.
cargo release patch
It turns a stressful, multi-step ritual into a single, reliable command. For someone who has fumbled manual releases before, this tool is a form of peace of mind.
After you’ve started depending on other people’s code, security becomes a concern. Those dependencies can have flaws. The Rust community maintains a database of known security vulnerabilities for crates, called the RustSec Advisory Database. Manually checking this is impossible. This is the job of cargo-audit.
You install it, and then it scans your Cargo.lock file, which is the exact snapshot of every library you’re using. It compares those versions against the database and tells you if you’re using a crate with a known problem.
cargo install cargo-audit
cargo audit
The real power is in automation. You can tell it to treat warnings as errors, which is perfect for a continuous integration (CI) pipeline. If a new vulnerability is discovered in a library you use, your build fails immediately, preventing the vulnerable code from ever reaching production.
cargo audit --deny warnings
It’s a simple, non-negotiable check. In today’s world, not using a tool like this is like leaving your front door unlocked.
Now, let’s say you want to use a fantastic Rust tool like ripgrep for code search or bat for syntax-highlighted file viewing. You could use cargo install. But that compiles the tool from source, which can take a very long time. I’ve waited over ten minutes for some tools to build. There has to be a better way.
There is. cargo-binstall stands for “binary install.” Instead of compiling, it fetches a pre-built binary for your system from crates.io and installs it. It’s incredibly fast.
cargo binstall ripgrep
Need a specific version? That’s easy too.
cargo binstall [email protected]
It feels like using a system package manager (apt, brew), but specifically for the universe of Rust binaries. The time savings, especially when setting up a new development machine, are enormous.
As your project grows, especially if you plan to distribute it, you need to think about licenses. Every open-source library you use comes with its own license (MIT, Apache, GPL, etc.). You are obligated to respect these terms. Keeping track by hand is a nightmare.
cargo-about creates a Software Bill of Materials for your dependencies. It lists every crate and its license. This output is often a legal requirement.
You can generate a clean HTML report to include with your project.
cargo about generate about.hbs > licenses.html
Or, for automated systems, you can produce JSON.
cargo about generate --format json > licenses.json
I once had to provide this for a corporate project. Doing it manually would have taken days of digging through Cargo.lock and source files. With cargo-about, it was a two-minute task. It turns a legal headache into a simple report.
Rust binaries are often praised for being fast, but sometimes they can be surprisingly large. If you’re targeting embedded systems, web browsers via WebAssembly, or even just want a small download for users, size matters. But how do you know what’s inside your binary? What’s taking up all that space?
cargo-bloat tells you. It analyzes your compiled executable and breaks down the size, crate by crate, and even function by function.
To see which dependencies are the biggest contributors:
cargo bloat --crates
To drill down and see the specific functions within your code and its dependencies that are creating the bulk:
cargo bloat --release -n 20
I used this on a WebAssembly project that was over 2MB. Running cargo-bloat showed me that a single utility crate I included for one small feature was pulling in 800KB of code. I found an alternative, and the size dropped dramatically. It’s a profiler, but for disk space instead of CPU time.
You’ve written a great application. How do you get it to users? You can’t ask them to install Rust and run cargo install. They need a normal installer: a .dmg on macOS, an .exe on Windows, a .deb on Ubuntu. Building these packages manually is a complex, platform-specific chore.
cargo-bundle automates this packaging. You give it some configuration in your Cargo.toml—like your app’s name and identifier—and it produces native bundles.
[package.metadata.bundle]
name = "MyApplication"
identifier = "com.example.myapp"
Then, a simple command creates the package for your current operating system.
cargo bundle --release
On a Mac, this would create MyApplication.app in target/release/bundle/osx/. It handles the intricacies of the platform’s packaging format for you. It bridges the gap between “it runs on my machine” and “here’s a file you can install.”
Rust workspaces are great for organizing large projects into multiple crates. But they can lead to a hidden problem: duplicated dependency builds. If two crates in your workspace depend on the same library but with slightly different feature sets, Cargo might compile that library twice. In a big project, this wastes a lot of time.
cargo-hakari solves this. It analyzes your entire workspace and generates a configuration that unifies the feature sets for shared dependencies. This ensures each library is built only once with a superset of the required features.
You start by generating its configuration file.
cargo hakari generate
Then, you use it to manage the unified dependencies.
cargo hakari manage
It integrates into your workspace’s root Cargo.toml. The first time I used it on a medium-sized workspace, my clean build time dropped by about 15%. For large monorepos, the savings can be massive. It’s a tool that pays for itself in saved compilation cycles.
Finally, before you publish your library to crates.io for the world to see, you should check what you’re about to upload. The cargo publish command is powerful but final. You don’t want to accidentally include a file with API keys, massive log files, or target build directories.
cargo package is your preview tool. It performs all the steps of creating the .crate file that would be uploaded, but it stops there and leaves it on your local machine.
cargo package --allow-dirty
Now you can inspect it. What’s inside that tarball?
tar -tzf target/package/my_crate-0.1.0.crate | head -20
You can see the exact list of files. No surprises. You can also run the verification step, which unpacks the file and builds it, ensuring the package is actually valid.
cargo package --verify
I’ve caught stray .env files and node_modules directories this way. It’s the final, crucial quality check before you make your code public.
Each of these tools focuses on a single, specific job in the lifecycle of a Rust project. They don’t replace cargo; they empower it. They take the friction out of processes that are otherwise manual, insecure, slow, or confusing. From the moment you add a dependency to the moment a user double-clicks your application, these tools help you do it right. They are what make Rust development not just powerful, but also polished and professional. Start with one that solves your most immediate headache, and you’ll soon find them all becoming essential parts of your toolkit.