How does [patch] in Rust work?

The [patch] feature in Rust allows developers to replace the source of a crate throughout the entire workspace. This ensures that every instance of the crate (for a given version) uses the patched version.

Why Can’t We Directly Replace the Crate Source?

You can, but [patch] ensures all instances of a crate in the workspace are replaced consistently.


Example: Patching the regex Crate

  1. Create a New Project:

cargo new patch

  1. Add regex as a Dependency:
[dependencies]
regex = "1.10.6"
  1. Run cargo tree to see the current crate tree:

cargo tree

You will see something like this:

patch v0.1.0 (<your-project-path>/patch)
└── regex v1.10.6
    ├── aho-corasick v1.1.3
    │   └── memchr v2.7.4
    ├── memchr v2.7.4
    ├── regex-automata v0.4.7
    │   ├── aho-corasick v1.1.3 (*)
    │   ├── memchr v2.7.4
    │   └── regex-syntax v0.8.4
    └── regex-syntax v0.8.4

Although the crate versions may differ, all the crates must still be fetched from crates.io. You can verify this by noting that no file path appears next to the version of the inner crates.

Patching regex-automata

Next, let’s patch the regex-automata crate with a local version:

  1. Clone the regex repository:

git clone https://github.com/rust-lang/regex

Ensure that you clone the crate version matching the one used in your project (in this case, you need to clone regex-automata version v0.4.7). If the versions don’t match, the crate will not be replaced successfully!

and in cloned regex repository in directory regex-automata we have this cloned crate.

  1. In Cargo.toml, add a patch directive:
[patch.crates-io]
regex-automata = {path = "regex/regex-automata"}

The patch section tells Cargo to use the local path for regex-automata instead of pulling it from crates.io.

Verify the Patch

Run cargo tree again, and you should see the path to the local regex-automata crate:

patch v0.1.0 (<your-project-path>/patch)
└── regex v1.10.6
    ├── aho-corasick v1.1.3
    │   └── memchr v2.7.4
    ├── memchr v2.7.4
    ├── regex-automata v0.4.7 (<your-project-path>/patch/regex/regex-automata)
    │   ├── aho-corasick v1.1.3 (*)
    │   ├── memchr v2.7.4
    │   └── regex-syntax v0.8.4 (<your-project-path>/patch/regex/regex-syntax)
    └── regex-syntax v0.8.4

Now, the regex crate will use your locally patched version of regex-automata.


We can also set [patch] as an option as --config 'patch.crates-io.<crate's-name>.path="<crates-name>"' (can be really useful for testing).


If you need to patch a crate originally imported from GitHub, replace [patch.crates-io] with [patch."github-path"] to target the correct source.


Ensure that the patch matches the exact version of the crate you are trying to replace!


Conclusion

The [patch] feature in Rust is a powerful way to override crate sources across an entire workspace, ensuring consistency and ease when working with dependencies.

0
Subscribe to my newsletter

Read articles from Yelyzaveta Dymchenko directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yelyzaveta Dymchenko
Yelyzaveta Dymchenko