Email me

Guide · 5 min read

Filed under Rust Guides

How to vendor Rust dependencies with cargo vendor for offline builds

Steps
6
Hands-on
15 min
Reading
5 min
Checked
Oct 26

The short version

Run cargo vendor in your project while you are online. It copies every dependency into a vendor/ folder and prints four lines of config; paste them into .cargo/config.toml. From then on Cargo reads crates from that folder instead of crates.io, so cargo build --offline --locked works with the cable unplugged. In our test, one dependency (serde_json) became 11 crates and 5,806 KB on disk, and Cargo resolved the whole tree with an empty cache in under a second.

Bar chart titled One dependency, 11 crates, all on disk. Size of each vendored crate for a project depending only on serde_json 1, in KB: syn 2,318, serde_json 747, memchr 580, serde 551, serde_core 386, unicode-ident 335, serde_derive 329, proc-macro2 267, quote 137, zmij 105, itoa 51.
What cargo vendor wrote for a project with one line in [dependencies]: 11 crates, 5,806 KB. Our run, cargo 1.91.0, Oct 26 2026. Chart by Tensorust from our own cargo vendor run.

What you need

  • Rust and Cargo installed (we used cargo 1.91.0)
  • A project with a Cargo.toml
  • Internet access once, to download the crates
  • About 5 to 500 MB of disk per project, depending on the dependency tree

Part of the article Offline Rust builds: 17,527 downloads, almost nobody is shutdown-ready. This page answers one question from it in depth.

On this page · 10 sections
  1. Before you start
  2. Commit a current Cargo.lock
  3. Run cargo vendor
  4. Point Cargo at vendor/
  5. Prove it with no network and an empty cache
  6. Ship vendor/ with the source
  7. Re-vendor when dependencies change
  8. What goes wrong
  9. When to use something bigger
  10. Sources

Every Rust build quietly assumes crates.io is one HTTPS call away. We counted what the ecosystem bets on that in Offline Rust builds: almost nobody is shutdown-ready: the six offline-build tools got 17,527 downloads in 90 days, while cargo-chef, which assumes the network is always there, got 1,218,032. Vendoring is free, built into Cargo, and takes about fifteen minutes. Own your supply chain while you still have a connection to copy it from.

Before you start

cargo vendor copies what your Cargo.lock says, so the lockfile is the source of truth. A library crate without a committed lockfile will get whatever versions resolve today. Also note the scope: vendoring covers crates. The Rust toolchain itself (rustc, cargo, std) still comes from rustup, so an offline machine needs its toolchain installed or mirrored separately.

Step 01: Commit a current Cargo.lock

While online, build once or run:

cargo generate-lockfile
git add Cargo.lock

If you already build in CI with --locked, you are done with this step.

Step 02: Run cargo vendor

cargo vendor

Our demo project had a single line in [dependencies], serde_json = "1". Cargo vendored 11 crates in 0.48 seconds (they were already in the local cache; a cold run downloads them first): itoa, memchr, proc-macro2, quote, serde, serde_core, serde_derive, serde_json, syn, unicode-ident and zmij.

Terminal capture: cargo vendor output listing vendored crates and the config to paste, then cargo tree resolving offline with an empty CARGO_HOME, then cargo add failing for anyhow because it is not in the vendor directory. Our run on Windows, cargo 1.91.0, Oct 26 2026. Trimmed: 7 of the 11 "Vendoring" lines and the local cache paths are cut for width.

Two details people miss. First, the folder holds more crates than your build uses: cargo tree showed 5 crates in the active tree, but vendor also copied serde_derive, syn, quote, proc-macro2 and unicode-ident, because the lockfile covers every feature and platform. Second, size is dominated by a few big crates. syn alone was 2,318 KB of our 5,806 KB. If the folder gets heavy, cargo-vendor-filterer drops crates for platforms you never build.

Useful flags from the cargo vendor docs: --versioned-dirs puts the version in every folder name (cleaner diffs when re-vendoring), -s path/to/Cargo.toml vendors extra workspaces into the same folder, and --locked fails instead of changing your lockfile.

Step 03: Point Cargo at vendor/

cargo vendor prints exactly what to add. Put it in .cargo/config.toml at the project root:

[source.crates-io]
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "vendor"

This is Cargo's source replacement: every request for a crates.io crate is answered from the directory instead. The Cargo book is strict about one rule here: the replacement must hold exactly the same code as the original, which is why you should never hand-edit files under vendor/. Each crate carries a .cargo-checksum.json, and Cargo treats vendored sources as read-only. To change a dependency, use [patch] or a path dependency.

Step 04: Prove it with no network and an empty cache

--offline alone can fool you, because Cargo may still find crates in your global cache (~/.cargo/registry). Point CARGO_HOME at an empty folder so the only possible source is vendor/:

CARGO_HOME=/tmp/empty-cargo-home cargo build --offline --locked

On Windows PowerShell: $env:CARGO_HOME="C:\temp\empty"; cargo build --offline --locked.

We ran the cheaper check, cargo tree --offline --locked, with an empty CARGO_HOME, and the full tree resolved from vendor/. Then we tried to add a crate we had not vendored, cargo add --offline anyhow@1, and got the failure you want to see: error: the crate anyhow@1 could not be found in registry index. Nothing leaked in from the network.

Step 05: Ship vendor/ with the source

Two common options:

  • Commit it. Simplest for air-gapped or regulated builds. Our 11-crate demo was under 6 MB; real services often run to hundreds of MB, so consider Git LFS or a separate branch.
  • Archive it. tar czf src-with-vendor.tgz Cargo.toml Cargo.lock .cargo src vendor gives the offline machine one file to unpack.

Step 06: Re-vendor when dependencies change

cargo vendor deletes and rewrites vendor/ by default (pass --no-delete to keep old contents). After cargo update or a new dependency, run it again online, review the diff, commit. Put cargo build --offline --locked in CI so a dependency added without re-vendoring fails the build the day it lands, not the day the network goes.

Troubleshooting

What goes wrong

  • "could not be found in registry index" offline: the crate is not in vendor/. You added a dependency after vendoring. Re-run cargo vendor online.
  • A checksum error naming a vendored file: someone edited a file under vendor/. Revert it and use [patch] instead.
  • Build passes on your laptop but fails on the offline box: your global cache was filling the gaps. Repeat Step 4 with an empty CARGO_HOME.
  • Git dependencies: these are vendored too, and the printed config then includes an extra [source."git+https://..."] block. Copy all of it, not just the crates-io part.
  • No toolchain: vendoring does not cover rustc itself. Install the toolchain on the offline machine first, or mirror it (the parent article covers panamax, which mirrors both and has not shipped a release since June 2024).

Bar chart titled cargo-chef outsells every offline tool combined. crates.io downloads in the last 90 days: cargo-chef 1,218,032, cargo-cache 61,329, cargo-local-registry 10,235, cargo-vendor-filterer 7,073, panamax 116, cargo-offline 59, ktra 37, freighter-server 7. The ecosystem's bet, in downloads. crates.io API, pulled Oct 26 2026.

When to use something bigger

cargo vendor is per project. If you run many projects offline, cargo-local-registry builds a reusable local registry from lockfiles (10,235 downloads in 90 days, the most popular offline tool we found), and a full crates.io mirror covers everything at the cost of a lot of disk. Start with vendoring: it needs nothing but Cargo.

Related: Offline Rust builds: almost nobody is shutdown-ready, GitHub outages and Rust crates, How to publish a Rust crate, Why crates.io download counts are inflated, and our free Cargo.toml checker.

Sources

All checked October 26, 2026.

  • The Cargo Book, cargo vendor: what the command copies, read-only vendored sources, --versioned-dirs, --no-delete, -s, --locked, --offline.
  • The Cargo Book, Source Replacement: replace-with, directory sources, the rule that a replacement must match the original source exactly.
  • crates.io: cargo-vendor-filterer, cargo-local-registry, panamax, cargo-chef; 90-day download counts from the crates.io API, pulled October 26, 2026.
  • Our own test: cargo 1.91.0 on Windows 11, a new project with serde_json = "1", cargo vendor, then cargo tree --offline --locked and cargo add --offline with an empty CARGO_HOME, October 26, 2026.
  • Tensorust, Offline Rust builds: almost nobody is shutdown-ready, October 26, 2026.

Do this next

Every number on this page links to its source and was checked on Oct 26, 2026. Spot an error or a newer figure? Email matt@tensorust.com and it gets fixed. Related: Cargo.toml checker, Check your crates.

Read next

Back to The Manual →   All articles →

Get the next one by email.

What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.

No spam, never sold. Every email has a one-click unsubscribe.

Up next

The article this answer comes fromOffline Rust builds: 17,527 downloads, almost nobody is shutdown-readyOffline Rust builds after Iran's 88-day blackout: 6 offline cargo tools got 17,527 downloads in 90 days, cargo-chef got 1.2M. How to vendor in an afternoon.Read it next →

Art: Nicholas Roerich, Depsang Plains (1925-26). Public domain, via Wikimedia Commons.

Get the receipts by email.

What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.

No spam, never sold. Every email has a one-click unsubscribe.

Did this answer your question?

Popular in the shop

All 124 tools →

Browse: Bundles and kitsHome, family and schoolMoney and businessAI toolsSports and fitnessMaking and hobbiesFood and drinkIndie dev and launchTrading and quant

Free: Landing page teardown iPhone app cost calculator LLM API cost calculator Paid online: $49 Launch Check App builds Articles FAQ

What are people saying about this? Read and post on The Floor →