Cargo source replacement redirects a source, usually crates.io, to another one through .cargo/config.toml. Use a registry mirror when you want a shared, cached copy for many builds, and vendoring when you want crates stored with the project. The replacement must hold exactly the same code as the original.
The core rule
The Cargo reference states that Cargo assumes the source code is exactly the same from both sources. A replacement also cannot contain crates that are absent from the original. So source replacement is not a way to patch a dependency, for which Cargo has the [patch] key. It is also not for private registries, which have their own chapter and configuration.
Mirror configuration
[source.crates-io]
replace-with = "my-mirror"
[source.my-mirror]
registry = "sparse+https://example.com/path/to/index"
The mirror follows the registry index specification and can use git, sparse HTTP or HTTPS git protocols. replace-with can also point to an alternative registry from the [registries] table.
Vendor configuration
[source.crates-io]
replace-with = "my-vendor-source"
[source.my-vendor-source]
directory = "vendor"
cargo vendor unpacks crate sources into a directory that you can check into version control. There is also a local registry type, a directory of crate files plus an index, usually synced with Cargo.lock.
Choosing
| Question | Mirror | Vendor |
|---|---|---|
| Shared across many projects | Yes | No, per project |
| Works offline | After caching | Yes, files are present |
| Review of changes | Server side | Diffs in pull requests |
| Repository size | Small | Larger |
| Ongoing upkeep | Run a service | Re-vendor on updates |
Vendoring makes a dependency update visible as a diff, which gives reviewers something to read. A mirror gives one place to apply logging and policy for the whole organisation.
What replacement does not give you
The docs say the .cargo-checksum.json file in directory sources is meant to detect accidental modification and is not a security mechanism. It does not protect against malicious changes. So vendoring does not prove that crates are safe. It freezes what you chose. You still need to review additions and scan them.
Mirroring also does not vet content. If the upstream carries a bad version and your mirror syncs it, you serve it.
Publishing note
When a source is replaced, commands that contact the registry directly, such as publishing commands, need the --registry option. That avoids ambiguity about which registry is contacted and selects the matching token.
Steps to adopt
- Pick mirror or vendor, based on the table.
- Commit
.cargo/config.tomlso every developer and CI job builds the same way. - For a mirror, restrict who can reach crates.io directly from build hosts.
- For vendoring, add a CI check that fails when
vendorandCargo.lockdisagree. - Scan the result and keep an SBOM per release.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at the dependency inventory and spot the transitive crates. Those are what a vendor directory quietly grows to include.
Safeguard's SBOM and dependency scanning can inventory the dependencies you pull, with a free scan at gold.safeguard.sh/scan.
Quick check
Can I use source replacement for a private registry?
The Cargo docs say no. Use the registries configuration for private crates.
Does vendoring make dependencies trustworthy?
No. The checksum file only detects accidental changes, so review and scan what you vendor.
Sources
Last reviewed: 19 October 2026.