Intermediate · Packages, testing and generics · topic 22 of 46 · 30 min
Dependencies with Go modules
Explanation
What a dependency is
A dependency is someone else's module that your code uses, for example a router, a database driver or a UUID generator. Go downloads modules from their source (usually a Git repository) through a module proxy, by default proxy.golang.org, a Google-run cache that keeps versions available even if the original repo disappears.
Adding a dependency
go get github.com/google/uuid@latest
go mod tidypackage main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
fmt.Println("order id:", uuid.NewString())
}module example.com/orders
go 1.24
require github.com/google/uuid v1.6.0go.sum: fingerprints
go.sum lists a cryptographic hash for every module version your build uses. If a download ever differs from the recorded hash, the build stops. Go also checks hashes against a public checksum database (sum.golang.org), so a malicious change to a published version would be noticed. Commit go.sum together with go.mod.
Semantic versions
| Part | Example change | Meaning |
|---|---|---|
| MAJOR (v1 → v2) | v1.9.0 → v2.0.0 | Breaking change: code using it may need edits |
| MINOR (v1.4 → v1.5) | v1.4.2 → v1.5.0 | New features, still compatible |
| PATCH (v1.4.2 → v1.4.3) | v1.4.2 → v1.4.3 | Bug fixes only |
| v0.x.y | v0.3.1 | Still unstable: anything may change |
Go's rule for major versions: from v2 on, the module path ends with /v2, /v3 and so on. So v4 and v5 of pgx are different import paths (github.com/jackc/pgx/v4 and github.com/jackc/pgx/v5), and a program can even use both during a migration.
Everyday commands
| Command | What it does |
|---|---|
| go get example.com/lib@v1.4.0 | Use exactly v1.4.0 |
| go get -u ./... | Update dependencies to newer minor/patch versions |
| go get example.com/lib@none | Remove a dependency |
| go mod tidy | Add missing and remove unused requirements |
| go list -m all | List every module in the build |
| go list -m -u all | Show which modules have updates |
| go mod why -m example.com/lib | Explain why a module is needed |
| go install example.com/tool@latest | Install a command-line tool into GOPATH/bin |
How Go picks versions
Go uses minimal version selection: for each module it picks the lowest version that satisfies every requirement in the build, not the newest one available. Builds therefore stay the same until someone deliberately changes go.mod. There is no separate lock file; go.mod plus go.sum is the lock.
Staying safe
- Prefer the standard library when it is good enough. Every dependency is code you must trust and update.
- Check a library before adding it: recent commits, a clear licence, real users, tests.
- Run govulncheck regularly. It reports known vulnerabilities that your code actually calls: go install golang.org/x/vuln/cmd/govulncheck@latest, then govulncheck ./...
- For private company repositories, set GOPRIVATE (for example GOPRIVATE=github.com/yourcompany/*) so Go fetches them directly and does not send their names to the public proxy or checksum database.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Dependencies with Go modules · 1/7
Real projects use other people's modules. Go modules manage them for you.
Prefer a video by a teacher? Find free videos on “go modules go get go mod tidy go.sum explained” on YouTube ↗
In real life: Adding a Postgres driver to an expense API
A team adds pgx v5 to talk to PostgreSQL. One go get records the version in go.mod and the checksums in go.sum. In CI, every build downloads exactly the same versions. Each month a developer runs go list -m -u all and govulncheck ./..., updates what is safe, runs the tests, and commits the two changed files.
go get github.com/jackc/pgx/v5@latest
go mod tidy
go build ./...
go test ./...
govulncheck ./...
git add go.mod go.sumPractice (0/4 done)
You removed the last import of a library from your code. Which command removes it from go.mod?
A library releases v3.0.0. What is its import path?
What does go.sum protect against?
In a new module, add github.com/google/uuid, print a new UUID, then look at go.mod and go.sum. Finally install and run govulncheck on the module.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Testing with go testPackages, testing and generics · same module
- Benchmarks and fuzz testsPackages, testing and generics · same module
- Semantic versioning, tags and releasesDevOps: Git, Docker, Kubernetes and CI/CD · Git in depth
- Node.js basicsJavaScript Programming (language in depth) · Performance and Node.js
- Packages and pubFlutter and Dart · Async Dart and packages
- Packages, crates and modulesRust Programming · Modules, crates, traits and generics
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Which version change usually means breaking changes?
Answer: Major
Semantic versioning reserves major versions for incompatible changes.
How does Go choose a dependency version by default?
Answer: The minimal version that satisfies all requirements
Minimal version selection keeps builds reproducible.
What does GOPRIVATE do?
Answer: Tells Go to fetch matching modules directly, not through the public proxy and checksum database
Use it for company-internal repositories.
How do you install a Go command-line tool at a version?
Answer: go install path@version
go install path@version builds the tool and puts it in GOPATH/bin (or GOBIN).
What is go.sum for?Related
Answer: It stores checksums of dependencies so tampered downloads are detected
go.sum holds a cryptographic checksum for every dependency version used.
Since the last release v3.1.4 there are commits: "fix: login timeout" and "feat: export to PDF". What is the next version?Related
Answer: 3.2.0
The feat is the highest change, so MINOR is bumped and PATCH reset: 3.2.0.
Does "^2.3.0" allow version 3.0.0?Related
Which command downloads the packages listed in pubspec.yaml?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 3 more topics in “Packages, testing and generics” before its exam: Testing with go test, Benchmarks and fuzz tests, Generics: type parameters and constraints.
- Module 5 exam: Packages, testing and generics · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Concurrency: goroutines, channels and context. 46 topics left in the course before the final exam.