Go Vendor Directory vs Go Modules: When to Use Each in Your Project

Use Go Modules for standard dependency management, and enable the vendor directory only when you require air-gapped reproducible builds or must satisfy strict compliance policies that mandate local source verification.

The golang-standards/project-layout repository defines industry standards for organizing professional Go codebases, including authoritative guidance on managing third-party dependencies. While Go Modules (introduced in Go 1.11 and stabilized in Go 1.14) provides the modern default workflow using go.mod files and the module proxy, the vendor directory remains a valid strategy for environments requiring guaranteed offline builds or source code audits.

How Go Modules Work

Go Modules declare dependencies in a go.mod file located at the repository root, allowing the Go toolchain to download packages automatically from the default module proxy (https://proxy.golang.org).

Core Files and Commands

The module system relies on two primary files:

  • go.mod – Declares the module path, Go version, and required dependencies with semantic versioning constraints.
  • go.sum – Contains cryptographic checksums that ensure reproducible builds by verifying the exact content of downloaded modules.

To initialize and use modules:


# Initialize a new module

go mod init github.com/yourname/awesomeapp

# Add a dependency (updates go.mod and downloads the module)

go get github.com/sirupsen/logrus@v1.9.0

# Build automatically fetches from proxy or local cache

go build ./...

A typical go.mod file looks like this:

module github.com/yourname/awesomeapp

go 1.22

require (
    github.com/sirupsen/logrus v1.9.0
    golang.org/x/net        v0.12.0
)

How the Vendor Directory Works

Vendoring creates a self-contained copy of every dependency inside the repository under the /vendor directory, eliminating the need for network access during builds.

Creating and Using Vendored Dependencies

According to the vendor/README.md in the golang-standards/project-layout repository, you populate the vendor directory using the modules system as the source of truth:


# Copy all dependencies from go.mod into ./vendor

go mod vendor

# Build using vendored code (required flag for Go < 1.14)

go build -mod=vendor ./...

# Run tests with vendored dependencies

go test -mod=vendor ./...

As noted in the repository's vendor documentation: "Note that you might need to add the -mod=vendor flag to your go build command if you are not using Go 1.14 where it's on by default." In Go 1.14 and later, the toolchain automatically detects and uses the /vendor directory if present, making the flag optional.

Go Vendor Directory vs Go Modules: Key Differences

Aspect Go Modules Vendor Directory
Storage location Dependencies live in the module cache or proxy; go.mod tracks versions only. Complete source code of dependencies copied into /vendor folder.
Network requirement Requires internet access (or private proxy) on first build unless cache is warm. Zero network access required after initial go mod vendor execution.
Repository size Smaller; only commit go.mod and go.sum. Larger; includes full source of all dependencies.
Build command go build ./... go build ./... (auto-detected in Go 1.14+) or go build -mod=vendor ./...
Audit compliance Relies on checksums in go.sum. Provides human-readable source code for security reviews.

When to Choose Each Approach

Follow this decision framework from the project-layout repository guidelines:

Choose Go Modules when:

  • You have reliable network access or a private module proxy.
  • You want smaller repository sizes and simpler CI/CD pipelines.
  • You are building a library intended for public consumption (vendoring is optional for libraries).

Choose the Vendor Directory when:

  • You need air-gapped reproducible builds without internet access.
  • Your organization requires source code audits of every dependency (regulated environments, financial services, government).
  • You are working behind a strict corporate firewall that blocks the public module proxy.

Practical Implementation Workflow

Standard Module Workflow

For most projects, commit only the module definition files:

go mod init github.com/yourorg/project
go get github.com/example/lib@v1.2.3
go mod tidy

# Commit go.mod and go.sum only

git add go.mod go.sum
git commit -m "Add dependencies"

Vendor-Enabled Workflow

For offline or audited environments:


# After establishing dependencies in go.mod

go mod vendor

# Commit the vendor directory (optional: add to .gitignore if not needed)

git add vendor/ go.mod go.sum
git commit -m "Vendor dependencies for offline builds"

The root README.md in the golang-standards/project-layout repository specifically discusses both approaches in the ### /vendor section, emphasizing that vendoring is a deliberate choice for specific constraints rather than the default pattern.

Summary

  • Go Modules (go.mod/go.sum) provide the default, network-based dependency management suitable for most modern Go projects.
  • Vendoring (go mod vendor + /vendor directory) creates local copies of dependencies for offline builds and audit compliance.
  • Go 1.14+ automatically uses the vendor directory when present; earlier versions require the -mod=vendor flag.
  • The golang-standards/project-layout repository documents both strategies, with specific guidance in vendor/README.md regarding flag usage and Go version differences.
  • Prefer modules for libraries and standard applications; prefer vendoring for regulated environments or air-gapped deployments.

Frequently Asked Questions

Do I need to commit the vendor directory if I already have go.mod?

No. If you use Go Modules, you only need to commit go.mod and go.sum. Commit the /vendor directory only if your build environment requires offline compilation or your security policy mandates local source verification. The golang-standards/project-layout repository treats vendoring as an optional addition to modules, not a replacement.

What is the difference between go.sum and the vendor directory?

go.sum stores cryptographic hashes that verify the integrity of downloaded modules, while the vendor directory stores the actual source code files. The checksum file ensures you get the exact same bits from the network, whereas vendoring ensures you have those bits locally without network access.

How do I build with vendored dependencies in older Go versions?

On Go versions prior to 1.14, you must explicitly pass the -mod=vendor flag to every build command: go build -mod=vendor ./.... Starting with Go 1.14, the toolchain automatically detects the /vendor directory and uses it by default, making the flag optional according to the vendor/README.md documentation.

Should I use vendoring for a public library I am publishing?

Generally, no. Published libraries should use Go Modules and provide a clean go.mod file. Vendoring is primarily intended for applications or specific CI/CD pipelines where reproducibility without network access is critical. Consumers of your library will resolve dependencies through their own module proxy or cache.

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 →