go mod tidy, vendor, download & graph
Module maintenance commands keep go.mod honest, warm caches, vendor sources for offline builds, and visualize why one version won over another.
Summary
go mod tidy aligns require directives with imports actually referenced in your module.
go mod download fetches modules into GOMODCACHE without compiling.
go mod vendor copies required module sources into vendor/ for -mod=vendor builds.
go mod graph prints the module requirement graph MVS consumed.
Use them after dependency changes, before release branches, and when debugging version selection.
Recipe
Quick-reference recipe card - copy-paste ready.
# Normalize requires after a refactor
go mod tidy
# Warm module cache in CI without compiling
go mod download all
# Materialize sources for air-gapped or audited builds
go mod vendor
# Inspect requirement edges (module@version pairs)
go mod graph | headWhen to reach for this:
- Run
go mod tidyon every PR that adds or removes imports. - Run
go mod downloadas an early CI step with a cachedGOMODCACHE. - Run
go mod vendorwhen policy requires reviewing third-party source in-repo. - Pipe
go mod graphinto graph tools when explaining a surprising transitive version.
Working Example
# Start from a module that imports x/sync
go get golang.org/x/sync@v0.10.0
# Add an import in code, remove another, then tidy
go mod tidy
# Pre-fetch everything the build list needs
go mod download all
# Vendor for -mod=vendor CI job
go mod vendor
# Build using only vendor/ + stdlib
go build -mod=vendor -o bin/worker ./cmd/worker
# See why v0.10.0 appears
go mod graph | rg 'golang.org/x/sync'// cmd/worker/main.go
package main
import (
"fmt"
"golang.org/x/sync/errgroup"
)
func main() {
var g errgroup.Group
g.Go(func() error { fmt.Println("task"); return nil })
_ = g.Wait()
}What this demonstrates:
go getrecords a version;tidyprunes anything no longer imported.downloadpopulates GOMODCACHE for faster later compiles.vendorplus-mod=vendorbuilds without reaching module proxies.go mod graphhelps audit edges after upgrades.
Deep Dive
How It Works
tidyloads all packages in the module, walks imports, and rewritesgo.modrequireblocks to the minimal set at chosen versions.- It also updates
go.sumwith hashes for direct and indirect modules retained. downloadresolves the build list and copies.ziparchives into the module cache; no.afiles are built.vendorrepeats download then extracts sources undervendor/<module>/, rewritinggo.modwith an optionalgo mod vendorcomment marker.
Command Reference
| Command | Modifies go.mod | Modifies vendor/ | Network |
|---|---|---|---|
go mod tidy | Yes | No | May fetch sums |
go mod download | No | No | Yes (unless cached) |
go mod vendor | Adds comment | Yes | Yes (unless cached) |
go mod graph | No | No | No |
go mod verify | No | No | No (local check) |
Vendor Workflow
# Typical regulated pipeline
go mod tidy
go mod vendor
git add go.mod go.sum vendor/
go test -mod=vendor ./...Graph and Why
# Explain a selected version
go mod why -m golang.org/x/sync
# JSON module list for SBOM tooling
go list -m -json allGotchas
- Committing tidy without tests - pruned requires may hide broken builds in unused packages. Fix:
go test ./...after every tidy. - Vendor drift - editing
go.modwithout re-vendoring breaks-mod=vendorCI. Fix: automatego mod vendorin the same commit as dependency bumps. - Huge vendor/ trees in libraries - consumers rarely want your copies. Fix: vendor in applications; publish libraries without
vendor/unless policy demands. - Assuming
downloadcompiles - it only fetches zips; compile errors appear later atgo build. Fix: follow download withgo testin CI. - Ignoring
go mod verifyfailures - indicates cache tampering or incompletego.sum. Fix: investigate proxy mirrors; do not delete sums blindly. - Indirect noise in go.mod - Go 1.17+ marks indirect requires; tidy keeps ones needed for MVS. Fix: trust tidy; use
go mod whyinstead of hand-editing.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
go work workspaces | Local multi-module dev without publishing | Single-module services |
replace directives | Temporary forks or local paths | Long-term version pinning (use proper tags) |
| Athens / Artifactory proxy | Shared module cache inside the org | Public open source with direct proxy.golang.org |
renovate / dependabot | Automated bump PRs | You lack CI to run tidy/test on each bump |
FAQs
What is the difference between go mod download and go get?
download fetches module content into the cache only.
go get also changes go.mod requirements.
When is vendoring required?
When builds must not contact module proxies (air gap) or compliance mandates reviewing third-party source in git.
Does tidy remove indirect requires?
It removes modules neither imported nor needed to satisfy MVS.
Some indirect lines remain when a transitive version matters.
What does go mod graph output mean?
Each line is parent@version child@version, a requirement edge before MVS pruning.
It is not identical to the final build list.
Can I vendor one dependency only?
go mod vendor vendors the full build list.
Selective vendoring is unsupported; use replace to a fork if you must trim.
How do I fix checksum mismatch errors?
Run go mod tidy or go get to refresh go.sum.
If mismatch persists, verify proxy integrity and module tags.
Should CI use -mod=readonly?
Yes for modules without vendor/.
It fails builds that would mutate go.mod silently.
What is GOMODCACHE?
The directory storing extracted module trees and zip caches.
Share it in CI caches to speed jobs.
How often should I run tidy?
After any change to imports or go get/go install that updates dependencies.
Many teams run it in pre-commit hooks.
Does vendor include test-only dependencies?
It includes modules needed to build packages in your module, including test imports.
Use go list -test to see test-only edges.
Related
- The go Command: Build, Test, and Module Lifecycle - MVS and build list
- Go Toolchain Basics - first
go mod tidyexample - Cross-Compilation & Private Module Proxies - GOPRIVATE and proxies
- go build, run, install & clean -
-mod=vendorbuilds - Go Toolchain Best Practices - dependency hygiene in CI
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).