Introduction
Go modules are the standard dependency management system since Go 1.11 (required since Go 1.16). Every Go project is a module with a go.mod file that declares its module path and dependencies. This guide covers everything from basic usage to advanced patterns like workspaces and private modules. See Go Installation Guide, Go Ecosystem Overview, Go Best Practices for more context.
The go.mod File
module github.com/myorg/myapp
go 1.22
require (
github.com/gin-gonic/gin v1.9.1
github.com/jackc/pgx/v5 v5.5.0
golang.org/x/sync v0.6.0
)
require (
// indirect dependencies (managed automatically)
github.com/bytedance/sonic v1.10.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
)
module— your module’s import path (usually matches your repository URL)go— minimum Go version requiredrequire— direct and indirect dependencies with exact versions
Initializing a Module
# Create a new module
mkdir myapp && cd myapp
go mod init github.com/myorg/myapp
# Creates go.mod:
# module github.com/myorg/myapp
# go 1.22
Adding Dependencies
# Add a specific package (updates go.mod and go.sum)
go get github.com/gin-gonic/gin
# Add a specific version
go get github.com/gin-gonic/[email protected]
# Add latest patch release (compatible with current minor)
go get github.com/gin-gonic/gin@latest
# Add a pre-release version
go get github.com/gin-gonic/[email protected]
# Add from a specific commit
go get github.com/gin-gonic/gin@abc1234
# Add from a branch
go get github.com/gin-gonic/gin@main
After go get, run your code or go mod tidy to update go.sum.
Essential go mod Commands
# Initialize a new module
go mod init github.com/myorg/myapp
# Add missing and remove unused dependencies
go mod tidy
# Download all dependencies to local cache
go mod download
# Copy dependencies to vendor/ directory
go mod vendor
# Verify dependencies haven't been tampered with
go mod verify
# Show why a module is needed
go mod why github.com/stretchr/testify
# Edit go.mod programmatically
go mod edit -require github.com/gin-gonic/[email protected]
go mod edit -droprequire github.com/old/package
# Show module graph
go mod graph
# Print module info
go list -m all # all dependencies
go list -m -json all # JSON format
go list -m -u all # show available updates
Upgrading Dependencies
# Upgrade a specific module to latest
go get github.com/gin-gonic/gin@latest
# Upgrade all direct dependencies to latest minor/patch
go get -u ./...
# Upgrade only patch versions (safer)
go get -u=patch ./...
# Check what's outdated
go list -m -u all | grep '\[v'
go mod tidy
go mod tidy is the most important command — run it after any dependency change:
go mod tidy
It:
- Adds missing
requireentries for packages you import - Removes
requireentries for packages you no longer import - Updates
go.sumwith checksums for all dependencies
Always commit both go.mod and go.sum.
Version Selection: Minimum Version Selection (MVS)
Go uses Minimum Version Selection — it picks the minimum version that satisfies all requirements. This is predictable and reproducible:
Module A requires: gin v1.8.0
Module B requires: gin v1.9.0
Result: gin v1.9.0 (minimum that satisfies both)
This means upgrading a dependency never happens automatically — you must explicitly request it.
Semantic Versioning and Major Versions
Go modules follow semantic versioning. Major version changes (v2+) require a different import path:
// v1 import
import "github.com/gin-gonic/gin"
// v2 import (different module path)
import "github.com/gin-gonic/gin/v2"
# Install v2
go get github.com/gin-gonic/gin/v2@latest
Replacing Dependencies
Replace a dependency with a local version or fork:
// go.mod
replace (
// Use a local fork
github.com/original/pkg => ../my-fork
// Use a different version
github.com/original/pkg v1.2.3 => github.com/myfork/pkg v1.2.3-patched
// Pin to a specific commit
github.com/original/pkg => github.com/original/pkg v0.0.0-20240101000000-abc123456789
)
# Add a replace directive
go mod edit -replace github.com/original/pkg=../my-fork
Remove replace directives before publishing — they only affect the module that declares them.
Vendor Directory
The vendor/ directory contains a copy of all dependencies for reproducible builds without network access:
# Create vendor directory
go mod vendor
# Build using vendor (ignores module cache)
go build -mod=vendor ./...
# Verify vendor matches go.mod
go mod verify
When to use vendor:
- CI/CD environments without internet access
- Auditing all dependency code
- Ensuring builds are reproducible without a module proxy
Private Modules
For private repositories, configure GONOSUMCHECK and GONOSUMDB:
# Tell Go not to use the public checksum database for private modules
export GONOSUMCHECK=github.com/myorg/*
export GONOSUMDB=github.com/myorg/*
export GOPRIVATE=github.com/myorg/* # combines both
# For GitHub with SSH authentication
export GOFLAGS=-mod=mod
git config --global url."[email protected]:".insteadOf "https://github.com/"
# .netrc for HTTPS authentication
machine github.com
login your-username
password your-personal-access-token
Go Workspaces (Go 1.18+)
Workspaces let you work on multiple modules simultaneously without replace directives:
# Create a workspace
go work init
# Add modules to the workspace
go work use ./myapp
go work use ./mylib
go work use ../shared-pkg
## go.work
go 1.22
use (
./myapp
./mylib
../shared-pkg
)
Now myapp can import mylib and shared-pkg using their actual module paths, and Go will use the local versions automatically.
# Sync workspace dependencies
go work sync
# Build all modules in workspace
go build ./...
Don’t commit go.work — it’s for local development only. Add it to .gitignore.
Module Proxy
Go downloads modules through a proxy (default: proxy.golang.org):
# Use the default proxy
export GOPROXY=https://proxy.golang.org,direct
# Use a corporate proxy
export GOPROXY=https://goproxy.mycompany.com,https://proxy.golang.org,direct
# Disable proxy (direct downloads only)
export GOPROXY=direct
# China mirror
export GOPROXY=https://goproxy.cn,direct
Common Patterns
Pinning a Dependency Version
# Pin to exact version (prevents accidental upgrades)
go get github.com/critical/[email protected]
// go.mod
require github.com/critical/pkg v1.2.3
Checking for Security Vulnerabilities
# Built-in vulnerability check (Go 1.20+)
go vuln check
# Or use govulncheck
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
Dependency Graph Visualization
# Install modgraphviz
go install golang.org/x/exp/cmd/modgraphviz@latest
# Generate dependency graph
go mod graph | modgraphviz | dot -Tpng -o deps.png
Quick Reference
| Command | Purpose |
|---|---|
go mod init <path> |
Initialize new module |
go mod tidy |
Add missing, remove unused deps |
go get <pkg>@<version> |
Add/update dependency |
go get -u ./... |
Upgrade all deps |
go mod download |
Download to cache |
go mod vendor |
Copy deps to vendor/ |
go mod verify |
Verify checksums |
go mod why <pkg> |
Why is this dep needed? |
go list -m -u all |
Show available updates |
Comments