Vendoring gives the strongest guarantee for one repository, a mirror serves many teams and fresh machines, and a cache is the cheapest but only covers what you have already fetched. Most teams end up with a cache plus a mirror, and vendoring for their most critical builds.
The three options
Vendoring copies dependencies into your repository or a build bundle. The Go toolchain, for example, uses a vendor directory automatically when one exists and the module declares a recent enough language version, loading packages from it instead of the network.
Cache stores what past builds downloaded. npm keeps a content-addressable cache on each machine, and CI systems can persist it between runs. GitHub's documentation notes cache entries unused for over 7 days are removed and that cache contents are not signed or verified.
Mirror is a server you run that fetches from the public source on demand and keeps a copy. Docker documents a registry in pull-through mode for images, with the caveat that it serves only what it has pulled or can fetch.
Comparison
| Factor | Vendoring | Cache | Mirror |
|---|---|---|---|
| Works on a fresh machine | Yes | No | Yes, if warmed |
| Covers new dependencies | No | No | Only if source is up |
| Needs hosting | No | Little | Yes |
| Reviewable change | Yes, in diffs | No | No |
| Setup effort | Low per repo | Low | Medium |
| Ongoing upkeep | Refresh on change | Expiry handling | Patching, storage, access |
| Risk of stale vulnerable copies | Yes | Yes | Yes |
A simple decision rule
- Is this build critical, such as your release or hotfix path? Vendor or archive its dependencies.
- Do many repositories and fresh CI runners need packages? Run a mirror.
- Do you only want faster installs? A cache is enough.
- Do you ship to environments with no internet? Use an offline bundle, such as a wheelhouse for Python.
What none of them solves
- Malicious or vulnerable versions. A copy serves what it copied. Scan the lockfile and the stored packages.
- Removed upstream packages. Only a copy made before removal helps, so warm early.
- Transitive and install time downloads. Test with the network off to find them.
- Access control. A mirror with broad credentials can expose private packages.
Prove it with an offline test
Pick one critical repository. Disconnect the network. Build from a clean checkout. The failures are your real coverage gaps. Repeat quarterly, since dependencies change.
Try it yourself
Click through it at your own pace, or open it full screen.
The inventory is the list your copy must cover. If a package appears there and not in your vendor folder, cache or mirror, an outage will find it.
Safeguard scans dependencies and generates SBOMs, so the list is kept current. Try the free scan.
Quick check
Can I just rely on the cache on my CI runners?
Only if those runners keep state. Ephemeral runners start empty, so a mirror or vendoring is safer.
Is a mirror a security control?
On its own, no. It improves availability. Security comes from scanning, review and policy applied to what the mirror serves.
Sources
- Go Modules Reference
- npm docs: npm cache
- GitHub Docs: Dependency caching reference
- Docker docs: Registry as a pull-through cache
Last reviewed: 19 October 2026.