🎓 A1Learner
🔍

Rust Patching Dependencies

A patch tells Cargo to use your copy instead of the registry copy. Nothing else in your project changes.

One table does the swap

The [patch] table names the registry, the crate, and the replacement folder:

[patch.crates-io]
itoa = { path = "../patched-itoa" }

The tree proves the swap

Run cargo tree before and after you add the table. The itoa line changes from the registry version to your folder and its version:

cargo tree

The replacement must fit the request

Your copy keeps the same crate name. Its version must satisfy the request in [dependencies]. Version 1.0.0 fits the request "1":

// in ../patched-itoa/Cargo.toml
[package]
name = "itoa"
version = "1.0.0"

A fix from git works too

A patch may point at a git repository instead of a folder. Pin it, like any git source:

[patch.crates-io]
itoa = { git = "https://github.com/example/itoa", branch = "fix" }

Your code cannot tell the difference

The patched copy must offer the same public items as the original. Calls written for the registry crate compile unchanged:

let mut buf = itoa::Buffer::new();
println!("the answer is {}", buf.format(42));

Example

// Cargo.toml
// [dependencies]
// itoa = "1"
// [patch.crates-io]
// itoa = { path = "../patched-itoa" }
fn main() {
    let mut buf = itoa::Buffer::new();
    println!("the answer is {}", buf.format(42));
}

Key points

  • Patch: a [patch] table entry that swaps one registry crate for a copy you choose, without editing any [dependencies] line
  • Use [patch.crates-io] to patch crates that come from crates.io
  • The patch table only counts in the workspace root manifest.
  • A [patch] table inside a library you depend on is ignored
  • The replacement keeps the crate name, and its version must satisfy the original version request
  • Send the fix upstream if you can.
  • A patch is a bridge, not a home: remove it when the registry catches up
  • A patch applies when a library you depend on has a bug and a fixed copy sits in a folder on your disk.

In this example, the program asks for itoa version "1" and calls it in the usual way. Without the patch table, Cargo builds the registry copy, version 1.0.18. With the patch table, Cargo builds the local copy instead. The program prints the same line either way. cargo tree is the honest witness: it shows the folder, not the registry, once the patch is in place.

Note

A patch never edits the registry crate itself.

Projects that depend on your library do not inherit your patch either.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

A bug in a registry crate breaks your project. You have a fixed copy in a local folder. What do you add?