Go Modules Cheat Sheet
Explains Go modules: initializing go.mod, adding and upgrading dependencies with go get, go mod tidy, and semantic versioning rules.
Initializing a Module
Creating go.mod and building the module.
go mod init github.com/username/myproject # Create go.mod, declares the module pathgo build ./... # Build all packages in the modulego run main.go # Compile and run
Managing Dependencies
Adding, upgrading, and cleaning up dependencies.
go get github.com/gin-gonic/[email protected] # Add a dependency at a specific versiongo get -u ./... # Upgrade all dependencies to latest minor/patchgo mod tidy # Add missing / remove unused dependenciesgo list -m all # List the module and all its dependencies
go.mod File
The declaration file for a module and its requirements.
module github.com/username/myprojectgo 1.22require ( github.com/gin-gonic/gin v1.9.1 github.com/stretchr/testify v1.8.4)require ( // indirect dependencies pulled in transitively github.com/bytedance/sonic v1.9.1 // indirect)
Concepts
How Go's module system resolves and verifies dependencies.
- go.mod- Declares the module path, Go version, and direct/indirect dependencies
- go.sum- Records cryptographic checksums of dependencies to ensure reproducible, verified builds
- Semantic versioning- Modules are versioned vX.Y.Z; major version 2+ requires a /vN suffix on the import path
- Minimal version selection- Go picks the minimum version satisfying all module requirements, not always the latest
- replace directive- replace old/module => ../local/path swaps a dependency for local development
- go mod tidy- Reconciles go.mod/go.sum with what the code actually imports
- GOPROXY- Environment variable controlling the module proxy used to fetch dependencies (default proxy.golang.org)
Multi-Module Workspaces (go.work)
Develop across several local modules simultaneously without editing go.mod replace directives.
go work init ./api ./worker ./shared # Create go.work referencing local modulesgo work use ./newmodule # Add another module to the workspacego build ./... # Builds using local module sources, not the networkcat go.work# go 1.22## use (# ./api# ./worker# ./shared# )# go.work is gitignored by convention -- it's a local dev convenience, not shipped
Version Queries with go get
Precisely control which version, commit, or branch a dependency resolves to.
go get example.com/[email protected] # Exact tagged versiongo get example.com/pkg@latest # Latest tagged (or default branch) versiongo get example.com/pkg@none # Remove the dependencygo get example.com/pkg@abcdef1 # Specific commit -- becomes a pseudo-versiongo get example.com/pkg@main # Track a branch (resolves to a pseudo-version)# Pseudo-version format for untagged commits:# v0.0.0-20240115120000-abcdef123456
replace & exclude Directives
Overriding or blocking specific module versions in go.mod.
module github.com/username/myprojectgo 1.22require github.com/acme/widgets v1.2.0// Point to a local checkout during developmentreplace github.com/acme/widgets => ../widgets// Point to a fork instead of the original module pathreplace github.com/acme/widgets => github.com/myfork/widgets v1.2.1-patched// Block a known-bad version from ever being selected transitivelyexclude github.com/broken/pkg v1.0.3
Private Modules & Vendoring
Fetching from private repos and freezing dependencies into the repository.
export GOPRIVATE=github.com/mycompany/* # Skip proxy + sumdb for these pathsexport GONOSUMCHECK=1 # Legacy equivalent on older toolchainsexport GOFLAGS=-mod=modgo mod vendor # Copy all dependencies into ./vendorgo build -mod=vendor ./... # Build using vendored copies, no network needed# CI tip: `go mod verify` checks vendored/downloaded modules against go.sum checksums
Advanced Module Concepts
Mechanics behind dependency resolution beyond the basics of go.mod.
- Module graph pruning- Since Go 1.17, go.mod records enough transitive requirements to avoid loading the full dependency graph for module-aware builds
- Major version suffix- v2 and above must include /v2 (etc.) in both the module path and every import path, per Go's semantic import versioning
- GOFLAGS / GOPROXY / GOSUMDB- GOPROXY controls the module mirror, GOSUMDB the checksum database used to verify authenticity, GONOSUMCHECK/GOPRIVATE bypass both for internal code
- go.work vs replace- go.work is a local, ungitted way to link modules for development; replace directives are committed and affect every consumer of the module
- Minimal version selection (MVS)- Go always picks the minimum version satisfying every require directive in the graph, favoring reproducibility over always-latest
- go mod graph- Prints the full requirement graph as edges, useful for tracing why a transitive dependency was pulled in
- go mod why- Explains why a package or module is needed, tracing the shortest import path that requires it
Run go mod tidy before every commit that changes imports — it keeps go.mod and go.sum in sync and catches unused or missing dependencies that would otherwise fail a clean CI build.