Go Modules: Finally, Official Dependency Management
Go 1.11 is out, and it includes modules (formerly vgo). Finally, official dependency management!
The Problem
Before modules, Go had:
- GOPATH (confusing for beginners)
- dep (community tool, not official)
- Vendor directories (manual management)
- No version pinning
It was a mess.
What Are Modules?
Modules are Go’s official dependency management system. They:
- Work outside GOPATH
- Pin dependency versions
- Use semantic versioning
- Generate lock files
Getting Started
# Initialize a module
go mod init github.com/myuser/myproject
# This creates go.mod
go.mod file:
module github.com/myuser/myproject
go 1.11
require (
github.com/gin-gonic/gin v1.4.0
github.com/lib/pq v1.2.0
)
Adding Dependencies
Just import and use:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.Run()
}
Then:
go build # Automatically downloads dependencies
Or explicitly:
go get github.com/gin-gonic/gin@v1.4.0
Semantic Versioning
Modules use semver:
# Latest version
go get github.com/gin-gonic/gin
# Specific version
go get github.com/gin-gonic/gin@v1.4.0
# Specific commit
go get github.com/gin-gonic/gin@abc123
# Latest patch release
go get github.com/gin-gonic/gin@v1.4
The go.sum File
go.sum is the lock file:
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
github.com/gin-gonic/gin v1.4.0/go.mod h1:58S9LJ4k/4vN6vVqXOnV3/3iwYDN9OZCaCsK0We9Rl8=
Commit this to version control.
Upgrading Dependencies
# Upgrade all dependencies
go get -u
# Upgrade specific dependency
go get -u github.com/gin-gonic/gin
# Upgrade to specific version
go get github.com/gin-gonic/gin@v1.5.0
Vendoring
Still want vendor directory?
go mod vendor
This copies dependencies to vendor/.
Migrating from dep
We had a project using dep:
# Remove dep files
rm Gopkg.lock Gopkg.toml
# Initialize modules
go mod init
# Tidy up
go mod tidy
Go modules automatically imported our dep dependencies!
Private Repositories
For private repos:
# Configure Git to use SSH
git config --global url."git@github.com:".insteadOf "https://github.com/"
# Set GOPRIVATE
export GOPRIVATE=github.com/mycompany/*
Multi-Module Repositories
You can have multiple modules in one repo:
myrepo/
├── go.mod # Root module
├── api/
│ └── go.mod # API module
└── worker/
└── go.mod # Worker module
Replace Directive
For local development:
// go.mod
module github.com/myuser/myproject
require github.com/myuser/mylib v1.0.0
replace github.com/myuser/mylib => ../mylib
Now changes to ../mylib are immediately reflected.
Our Experience
We migrated 10 projects from dep to modules. It was smooth:
- Run
go mod init - Run
go mod tidy - Test
- Commit
go.modandgo.sum
Total time: ~1 hour for all projects.
Benefits
1. No More GOPATH
Projects can live anywhere:
cd ~/projects/myapp # Not in GOPATH
go build # Works!
2. Reproducible Builds
go.sum ensures everyone gets the same dependencies.
3. Faster Downloads
Module cache is shared across projects:
# Cache location
~/go/pkg/mod/
4. Semantic Versioning
Clear versioning makes upgrades safer.
Issues We Hit
1. v2+ Modules
Modules v2+ must include version in import path:
// v1
import "github.com/myuser/mylib"
// v2
import "github.com/myuser/mylib/v2"
This is confusing but necessary for compatibility.
2. Pseudo-Versions
Untagged commits get pseudo-versions:
v0.0.0-20180901003855-c67002cb31c3
Ugly but functional.
3. Minimal Version Selection
Go modules use “minimal version selection”, not “latest version selection”.
This can be surprising but is more predictable.
Should You Use Modules?
Yes, if:
- Starting a new project
- Want to work outside GOPATH
- Need reproducible builds
Wait, if:
- On Go < 1.11
- dep is working fine for you
We’re using modules for all new projects. Migrating old projects gradually.
The Future
Modules are the future of Go dependency management. dep is deprecated.
Go 1.13 will make modules the default.
Commands Cheat Sheet
# Initialize
go mod init github.com/user/repo
# Add dependency
go get github.com/pkg/errors
# Upgrade all
go get -u
# Tidy up
go mod tidy
# Vendor
go mod vendor
# Verify
go mod verify
# Graph
go mod graph
The Verdict
Go modules are a huge improvement. They’re simple, official, and work well.
If you’re not using them yet, give them a try.
Questions? Let me know!