Skip to content

clovu/cargo-upgrade

Repository files navigation

cargo-upgrade

cargo-upgrade is a Cargo subcommand for refreshing dependency version requirements in Cargo.toml.

It is inspired by the ergonomics of pnpm upgrade: inspect the dependencies in a project, resolve newer crate releases from crates.io, then rewrite manifest requirements when an upgrade is available.

The tool changes dependency requirements in Cargo.toml. It is not a wrapper around cargo update, and it is not limited to updating Cargo.lock.

Installation

cargo install cargo-upgrade

Or install from source:

git clone https://github.com/clovu/cargo-upgrade.git
cd cargo-upgrade
cargo install --path .

After installation, Cargo can run the binary as a subcommand:

cargo upgrade

Quick Start

cargo upgrade
cargo upgrade --dry-run
cargo upgrade --latest
cargo upgrade --interactive
cargo upgrade --prod
cargo upgrade --dev
cargo upgrade serde tokio

What It Does

The current implementation:

  1. Reads Cargo.toml from the current crate root.
  2. Collects dependencies from the top-level dependency tables:
    • [dependencies]
    • [dev-dependencies]
    • [build-dependencies]
  3. Queries crates.io for available releases.
  4. Chooses a target version for each dependency.
  5. Rewrites only the dependency requirement in Cargo.toml.

The dependency-table model is intended to grow beyond those top-level tables. Planned coverage includes target-specific dependency tables such as [target.'cfg(target_os = "windows")'.dependencies], plus the corresponding target-specific dev-dependencies and build-dependencies tables.

For inline-table dependencies, only the version field is changed:

tokio = { version = "1.44.2", features = ["rt-multi-thread", "macros"] }

becomes:

tokio = { version = "1.52.2", features = ["rt-multi-thread", "macros"] }

Other fields, such as features, optional, default-features, and similar manifest settings, are preserved.

Version Requirement Behavior

By default, cargo-upgrade chooses the newest release that still satisfies the current version requirement.

Examples:

serde = "1.0"
tokio = "~1.2.0"
clap = "=4.5.0"

With the default mode:

  • serde = "1.0" can move to a newer 1.x release allowed by the requirement.
  • tokio = "~1.2.0" stays inside the compatible tilde range.
  • clap = "=4.5.0" keeps exact-version semantics.

With --latest, the command ignores the current requirement range and targets the newest release available from crates.io. It still preserves the visible requirement style when rewriting:

tokio = "~1.2.0"

can become:

tokio = "~1.52.2"

If the current requirement already points at the latest release, no update is produced.

The wildcard requirement * is rewritten to a concrete caret requirement for the selected release.

Command Options

Status meanings:

  • Implemented: supported by the current runtime.
  • Defined, not implemented: accepted by the CLI definition, but rejected before upgrade work begins.
  • Built in: generated by clap.
Option Status Description
[CRATE]... Implemented Upgrade only the named crates. Matching is exact by dependency key. Repeatable.
-L, --latest Implemented Ignore the current requirement range and target the latest available crates.io release.
--dry-run Implemented Print planned changes without writing Cargo.toml.
-i, --interactive Implemented Open a tree-style TUI for selecting which upgrades to apply.
-P, --prod Implemented Upgrade production dependency groups. Today this means top-level [dependencies] and [build-dependencies]; target-specific production groups are planned. Conflicts with --dev.
-D, --dev Implemented Upgrade development dependency groups. Today this means top-level [dev-dependencies]; target-specific development groups are planned. Conflicts with --prod.
-r, --recursive Defined, not implemented Intended for recursive workspace traversal. Currently rejected.
-g, --global Defined, not implemented Intended for upgrading globally installed Cargo binary crates. Currently rejected.
--workspace Defined, not implemented Intended for workspace-aware behavior. Currently rejected.
--no-optional Defined, not implemented Intended to skip optional dependencies. Currently rejected.
--filter <FILTER> Defined, not implemented Intended to filter target workspace crates. Repeatable. Currently rejected.
--depth <N> Defined, not implemented Intended to limit recursive traversal depth. Currently rejected.
-h, --help Built in Print help text.
-V, --version Built in Print the package version.

Option Details

Selecting Crates

Pass crate names as positional arguments:

cargo upgrade serde tokio

This filters by the dependency key in Cargo.toml.

Pattern matching and wildcard crate-name filters are not implemented yet.

Latest Mode

cargo upgrade --latest

This mode targets the newest release available from crates.io, even if it is outside the current requirement range.

Dry Run

cargo upgrade --dry-run

This prints the upgrade plan and leaves Cargo.toml unchanged.

Interactive Mode

cargo upgrade --interactive

or:

cargo upgrade -i

Interactive mode opens a TUI with a tree layout:

dependencies
  serde
  tokio

devDependencies
  insta

buildDependencies
  cc

The tree groups upgrades by dependency section. The detail panel shows the current requirement, target requirement, impact classification, and selected state for the current node.

Common keys:

Key Action
Up, Down, j, k Move cursor
Left, Right, h, l Collapse or expand sections
e Toggle section expansion
Space Toggle selected upgrade or whole section
a Select all or select none
i Invert selection
Enter Apply selected upgrades
Esc, q, Ctrl-C Cancel

Production Dependencies

cargo upgrade --prod

This scans production dependency groups. Today that includes:

  • [dependencies]
  • [build-dependencies]

It skips development dependency groups. Target-specific production dependency tables are planned but not scanned yet.

Development Dependencies

cargo upgrade --dev

This scans development dependency groups. Today that includes:

  • [dev-dependencies]

Target-specific development dependency tables are planned but not scanned yet.

Current Limitations

cargo-upgrade is still early and intentionally conservative.

Current limitations:

  • It must be run from a crate root containing Cargo.toml.
  • Workspace-recursive upgrades are not implemented.
  • Target-specific dependency sections, such as [target.'cfg(target_os = "windows")'.dependencies], are not scanned yet.
  • Inherited workspace dependencies are skipped.
  • Dependencies without an explicit version field are skipped.
  • crates.io lookup failures are reported, but do not stop the whole run.
  • Only crates.io release lookup is supported.
  • Optional dependency filtering is not implemented.
  • Global Cargo binary crate upgrades are not implemented.
  • Positional crate filters use exact names only. Patterns and globs are not implemented.

Project Direction

The goal is to make upgrading Rust dependency requirements feel as natural as pnpm upgrade does in JavaScript projects, while respecting Cargo manifest structure and Rust workflow expectations.

Long-term areas include:

  • Workspace traversal.
  • Workspace-aware filtering.
  • Target-specific dependency tables.
  • Global Cargo binary crate upgrades.
  • Optional dependency filtering.
  • Better source handling for non-crates.io dependencies.
  • Richer interactive review.

License

MIT License © 2026 Clover You

Releases

No releases published

Packages

 
 
 

Contributors

Languages