๐ŸŽ“ A1Learner
๐Ÿ”

Rust Vendoring & Offline Builds

Vendoring is copying every library a project needs into the project itself. After vendoring, builds need no network at all.

Pack the libraries into the project

cargo vendor copies every library in your lockfile into a folder, source code and all:

cargo vendor vendor

Cargo prints the switch

The command ends by printing a small config. It tells Cargo to read the vendor folder instead of crates.io:

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

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

Work without any network

Save that config as .cargo/config.toml in the project. Then this flag forbids network use for one build, and the build reads only local files:

cargo build --offline

Frozen means no surprises

--frozen goes one step further. It also refuses to update Cargo.lock, so a build server proves it used the recorded versions:

cargo build --frozen

The same program, built offline

This program uses itoa from the vendor folder. It ran with --offline, and no network at all:

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

Example

// Cargo.toml: itoa = "1" under [dependencies]
// One-time setup on a connected machine:
// cargo vendor vendor
// (save the printed config as .cargo/config.toml)
fn main() {
    let mut buf = itoa::Buffer::new();
    println!("the answer is {}", buf.format(42));
}

Key points

  • Vendoring: copying every dependency's source into your project, so the project carries its libraries with it
  • Use cargo vendor <folder> to make the copy.
  • The command prints the config that points Cargo at the folder.
  • The config lives in .cargo/config.toml in the project root.
  • It replaces the crates.io source with the folder.
  • Use cargo build --offline to forbid network for one run.
  • Use --frozen to also forbid any change to Cargo.lock.
  • Vendor again after every version change, so the folder keeps matching Cargo.lock
  • You can read every line your program depends on, and diff it when versions change.
  • A download cache gives you neither.

In this example, the program uses itoa in the ordinary way. The difference is where Cargo found itoa. The setup copied itoa's source into a vendor folder inside the project. The config then pointed Cargo at that folder. The build and the run above happened with --offline. No network was involved.

Note

The vendor folder is plain source code.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท Rust Playground

Exercise

Your build server has no network. Your project uses crates.io libraries. The standard preparation is: