Go modules revolutionized dependency management in Go. Before Go 1.11, managing dependencies was challenging and error-prone. Modules provide a clean, reproducible way to manage project dependencies with semantic versioning. This guide covers everything you need to master Go modules. For more context, see Go Installation Guide, Go Ecosystem Overview, Go Best Practices.
Understanding Go Modules
A Go module is a collection of Go packages stored in a file tree with a go.mod file at its root. The go.mod file defines the module’s identity and its dependency requirements.
What is go.mod?
The go.mod file specifies:
- The module name (import path)
- The Go version
- Required dependencies and their versions
- Indirect dependencies
Example go.mod:
module github.com/username/myapp
go 1.21
require (
github.com/gin-gonic/gin v1.9.1
github.com/lib/pq v1.10.9
)
require (
github.com/google/uuid v1.3.0 // indirect
)
What is go.sum?
The go.sum file contains cryptographic hashes of module versions. It ensures that dependencies haven’t been tampered with and provides reproducible builds.
github.com/gin-gonic/gin v1.9.1 h1:...
github.com/gin-gonic/gin v1.9.1/go.mod h1:...
github.com/lib/pq v1.10.9 h1:...
github.com/lib/pq v1.10.9/go.mod h1:...
Initializing a Module
Creating a New Module
mkdir myapp
cd myapp
go mod init github.com/username/myapp
This creates a go.mod file:
module github.com/username/myapp
go 1.21
Module Naming Conventions
Module names should follow the pattern:
domain/username/projectname
Examples:
github.com/golang/go- Official Go repositorygithub.com/sirupsen/logrus- Popular logging librarygitlab.com/mycompany/internal-tool- Internal toolexample.com/myteam/service- Company service
For private modules, use your domain or company domain.
Adding Dependencies
Adding a Dependency
go get github.com/gin-gonic/gin
This:
- Downloads the latest version
- Updates
go.modwith the requirement - Updates
go.sumwith hashes - Makes the package available for import
Specifying Versions
# Latest version
go get github.com/gin-gonic/gin
# Specific version
go get github.com/gin-gonic/[email protected]
# Latest patch version
go get github.com/gin-gonic/[email protected]
# Latest minor version
go get github.com/gin-gonic/gin@v1
# Latest pre-release
go get github.com/gin-gonic/gin@latest
# Specific commit
go get github.com/gin-gonic/gin@abc123def456
# Branch
go get github.com/gin-gonic/gin@main
Updating Dependencies
# Update all dependencies to latest patch versions
go get -u ./...
# Update all dependencies to latest minor/major versions
go get -u -t ./...
# Update specific dependency
go get -u github.com/gin-gonic/gin
# Update to specific version
go get github.com/gin-gonic/[email protected]
Semantic Versioning
Go modules use semantic versioning: MAJOR.MINOR.PATCH
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
Examples:
v1.0.0→v1.0.1- Patch releasev1.0.0→v1.1.0- Minor releasev1.0.0→v2.0.0- Major release
Version Constraints
In go.mod, you can specify version constraints:
require (
github.com/gin-gonic/gin v1.9.1 // Exact version
github.com/lib/pq >= v1.10.0 // Minimum version
github.com/google/uuid < v2.0.0 // Maximum version
github.com/sirupsen/logrus >= v1.8.0, < v2.0.0 // Range
)
Managing go.mod and go.sum
Tidying Dependencies
# Remove unused dependencies and add missing ones
go mod tidy
This is the most important command. Run it regularly to keep your module clean.
Downloading Dependencies
# Download all dependencies
go mod download
# Download specific dependency
go mod download github.com/gin-gonic/[email protected]
Verifying Dependencies
# Verify all dependencies
go mod verify
# Check for security vulnerabilities
go list -json -m all | nancy sleuth
Viewing Dependency Graph
# Show all dependencies
go mod graph
# Show dependencies in tree format
go mod graph | head -20
# Using go list
go list -m all
Working with Private Modules
Configuring Git Credentials
For private repositories on GitHub:
# Configure git to use SSH
git config --global url."[email protected]:".insteadOf "https://github.com/"
# Or use personal access token
git config --global url."https://USERNAME:[email protected]/".insteadOf "https://github.com/"
Using Private Modules
# Add private module
go get github.com/mycompany/private-lib
# In go.mod
require github.com/mycompany/private-lib v1.0.0
GOPRIVATE Configuration
# Mark modules as private (skip proxy)
export GOPRIVATE=github.com/mycompany/*
# Or in go.env
go env -w GOPRIVATE=github.com/mycompany/*
Module Proxies and Checksums
Using a Module Proxy
# Use official Go proxy (default)
export GOPROXY=https://proxy.golang.org
# Use multiple proxies
export GOPROXY=https://proxy.company.com,https://proxy.golang.org
# Disable proxy (use direct)
export GOPROXY=direct
# Use local proxy
export GOPROXY=file:///path/to/local/proxy
Checksum Database
# Use official checksum database (default)
export GOSUMDB=sum.golang.org
# Disable checksum verification
export GOSUMDB=off
# Use custom checksum database
export GOSUMDB=sum.company.com
Common Module Operations
Replacing Dependencies
Sometimes you need to use a different version or fork:
# In go.mod
replace github.com/gin-gonic/gin => github.com/mycompany/gin v1.9.1
# Or use local path
replace github.com/gin-gonic/gin => ../local-gin
Excluding Versions
# In go.mod
exclude github.com/gin-gonic/gin v1.8.0
Retraction
If you publish a bad version, retract it:
// In go.mod
retract v1.0.0
retract [v1.0.0, v1.0.5]
Best Practices
✅ Good Practices
- Commit go.mod and go.sum - Always commit both files to version control
- Run go mod tidy regularly - Keep dependencies clean
- Use specific versions - Avoid
latestin production - Review dependency updates - Check changelogs before updating
- Use semantic versioning - Follow MAJOR.MINOR.PATCH
- Document dependencies - Include rationale for major dependencies
- Keep dependencies minimal - Only add what you need
- Update regularly - Stay current with security patches
❌ Anti-Patterns
// ❌ Bad: Committing vendor directory (usually)
// Only commit if you need offline builds
// ❌ Bad: Using latest in production
require github.com/gin-gonic/gin latest
// ❌ Bad: Ignoring go.sum
// Always commit go.sum for reproducibility
// ❌ Bad: Not running go mod tidy
// Leaves unused dependencies
// ❌ Bad: Using replace in published modules
// Only use replace for local development
// ❌ Bad: Circular dependencies
// Restructure to eliminate cycles
Troubleshooting
Module Not Found
# Problem: "cannot find module"
# Solution 1: Ensure module is public or credentials are configured
go get github.com/username/module
# Solution 2: Check GOPRIVATE
export GOPRIVATE=github.com/mycompany/*
# Solution 3: Use direct download
export GOPROXY=direct
go get github.com/username/module
Version Conflicts
# Problem: "conflicting requirements"
# Solution: Use go mod tidy to resolve
go mod tidy
# Or manually edit go.mod to compatible versions
Checksum Mismatch
# Problem: "checksum mismatch"
# Solution 1: Clear cache and re-download
go clean -modcache
go mod download
# Solution 2: Disable checksum verification (not recommended)
export GOSUMDB=off
Vendoring
For offline builds or reproducibility:
# Create vendor directory
go mod vendor
# Use vendor directory
go build -mod=vendor
# Commit vendor directory
git add vendor/
git commit -m "Add vendor dependencies"
Advanced Module Features
Module Directives
// In go.mod
// Specify Go version
go 1.21
// Require specific versions
require github.com/gin-gonic/gin v1.9.1
// Indirect dependencies (managed automatically)
require github.com/google/uuid v1.3.0 // indirect
// Replace with local path
replace github.com/gin-gonic/gin => ../local-gin
// Replace with different version
replace github.com/gin-gonic/gin => github.com/mycompany/gin v1.9.1
// Exclude versions
exclude github.com/gin-gonic/gin v1.8.0
// Retract versions
retract v1.0.0
Workspace Mode
For working with multiple modules:
# Create go.work
go work init ./module1 ./module2 ./module3
# Add modules
go work use ./module4
# Remove modules
go work edit -dropuse=./module4
Resources and References
Official Documentation
- Go Modules Documentation - Complete modules reference
- Go Module Proxy - Official module proxy
- Go Checksum Database - Official checksum database
Recommended Reading
- Using Go Modules - Official blog post
- Go Modules by Example - Practical examples
- Semantic Versioning - Version numbering guide
Tools and Resources
- pkg.go.dev - Go package documentation
- Go Module Tidy - Official documentation
- Dependency Management Best Practices - Community guide
Summary
Go modules provide a robust, reproducible way to manage dependencies:
- Initialize with
go mod init - Add dependencies with
go get - Keep dependencies clean with
go mod tidy - Always commit
go.modandgo.sum - Use semantic versioning
- Review updates before applying
- Use
go mod vendorfor offline builds
Mastering modules is essential for professional Go development.
Comments