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

> Understand the purpose of go mod vendor. Learn how to copy dependencies to a vendor directory for reproducible offline builds and legacy tool compatibility in Go.

- Repository: [Go/go](https://github.com/golang/go)
- Tags: internals
- Published: 2026-02-20

---

**`go mod vendor` copies all of a module's build-time dependencies into a local `vendor` directory and generates a [`vendor/modules.txt`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modload/vendor.go).

## Practical Usage Examples

Create a vendor directory for the current module:

```bash
go mod vendor

```

Build using the vendored copy without network access:

```bash
go build -mod=vendor ./...

```

Inspect the generated manifest:

```bash
cat vendor/modules.txt

```

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

```bash
go mod vendor -o ./third_party/vendor

```

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

```bash
go mod vendor -e

```

In a workspace, vendor all modules at once:

```bash
go work vendor

```

## Summary

- **`go mod vendor`** creates a local `vendor` directory containing all build-time dependencies and a [`modules.txt`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/modules.txt) manifest for verification.

### Does `go mod vendor` include test files?

No. The `matchPotentialSourceFile` function in [`src/cmd/go/internal/modcmd/vendor.go`](https://github.com/golang/go/blob/main/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`](https://github.com/golang/go/blob/main/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.