What Is the Purpose of `go mod vendor` in Go Modules?

go mod vendor copies all of a module's build-time dependencies into a local vendor directory and generates a vendor/modules.txt manifest, enabling reproducible offline builds and compatibility with legacy GOPATH-mode tools.

When working with Go modules in the golang/go repository, the go mod vendor command serves as a materialization tool that freezes your dependency graph into the filesystem. This ensures that your project's build requirements are self-contained, allowing compilation without external network access while maintaining explicit version tracking through the generated manifest.

Core Purpose and Benefits of go mod vendor

The go mod vendor command addresses several specific needs in the Go module ecosystem:

Reproducible Offline Builds

By materializing the exact source code of every required module into the vendor directory, builds no longer depend on external proxies or network access. This ensures that the same code is compiled every time, regardless of network availability or upstream repository changes.

Compatibility with GOPATH-Mode Tools

The vendor layout intentionally mimics the GOPATH src tree structure. This allows legacy tools and workflows that expect dependencies to reside in ./vendor to locate and use the correct packages without modification.

Controlled Vendoring Scope

The command deliberately excludes non-essential artifacts. According to the implementation in src/cmd/go/internal/modcmd/vendor.go, the matchPotentialSourceFile filter removes test files (*_test.go) and, for Go versions 1.17 and later, omits go.mod and go.sum files from the vendored copy. Only files necessary for building your application are preserved.

Explicit Version Tracking

The generated vendor/modules.txt file records the selected module versions and any replace directives. This manifest allows the -mod=vendor build mode to verify consistency and reject mismatched vendoring, ensuring the build uses exactly what was intended.

How go mod vendor Works Under the Hood

The implementation in src/cmd/go/internal/modcmd/vendor.go orchestrates a multi-step process to create the vendor directory:

Loading Packages Across the Module Graph

The command begins by loading all packages using modload.LoadPackages(..., "all") with the options UseVendorAll: true and AllowErrors (when the -e flag is specified). This ensures that every transitive dependency required for building is identified, even if some packages contain errors.

Grouping by Module

After loading, the system groups packages by the module that provides them (modpkgs). This organization ensures that each module's source files are consolidated into the appropriate subdirectory within vendor/.

Filtering Source Files

Before copying, each file passes through the matchPotentialSourceFile test. This filter excludes test files and metadata files that are not required for compilation, ensuring the vendor directory contains only build-essential code.

Generating the Manifest

The command writes vendor/modules.txt using the moduleLine function to describe each vendored module, including any replacement paths specified in your go.mod. This manifest serves as the source of truth when verifying vendored dependencies during builds.

Copying Source and Metadata

Valid source files are copied into the target vendor directory via vendorPkg, while module metadata such as LICENSE and NOTICE files are preserved through copyMetadata. This ensures compliance with license requirements while maintaining a clean source tree.

Workspace Support

For multi-module workspaces, the go work vendor command (implemented in src/cmd/go/internal/workcmd/vendor.go) performs the same operation at the workspace level. Low-level helpers for reading existing vendor manifests and checking consistency reside in src/cmd/go/internal/modload/vendor.go.

Practical Usage Examples

Create a vendor directory for the current module:

go mod vendor

Build using the vendored copy without network access:

go build -mod=vendor ./...

Inspect the generated manifest:

cat vendor/modules.txt

Vendor to a custom location (useful for external tooling):

go mod vendor -o ./third_party/vendor

Continue even if some packages fail to load (e.g., missing test files):

go mod vendor -e

In a workspace, vendor all modules at once:

go work vendor

Summary

  • go mod vendor creates a local vendor directory containing all build-time dependencies and a modules.txt manifest.
  • It enables reproducible offline builds by removing network dependencies during compilation.
  • The command excludes test files and unnecessary metadata through the matchPotentialSourceFile filter.
  • It maintains GOPATH compatibility for legacy tooling expecting the ./vendor layout.
  • The -mod=vendor build flag uses vendor/modules.txt to verify consistency and ensure deterministic builds.
  • Workspace support via go work vendor extends vendoring to multi-module workspaces.

Frequently Asked Questions

What is the difference between go mod vendor and go mod download?

go mod download caches module source code in the local module cache (typically $GOPATH/pkg/mod) but does not copy files into your project directory. In contrast, go mod vendor copies dependencies into a local vendor directory within your project, allowing version control of dependencies and offline builds. The vendor directory also excludes test files and generates a modules.txt manifest for verification.

Does go mod vendor include test files?

No. The matchPotentialSourceFile function in src/cmd/go/internal/modcmd/vendor.go explicitly filters out files matching *_test.go. This keeps the vendor directory focused strictly on build-time dependencies, reducing repository size and avoiding potential test-related errors in vendored code.

How do I build using vendored dependencies?

Use the -mod=vendor flag with standard build commands. For example: go build -mod=vendor ./.... This tells the Go toolchain to use the sources in the vendor directory instead of the module cache, verifying against vendor/modules.txt to ensure the vendored code matches the expected versions.

Can I customize the vendor directory location?

Yes. You can specify a custom output directory using the -o flag: go mod vendor -o ./third_party/vendor. This is particularly useful when integrating with external tooling that expects dependencies in specific locations, though the standard vendor/ directory is recommended for most projects to ensure -mod=vendor works correctly without additional configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →