Adding and Tidying Dependencies with go get and go mod tidy
How to add, update and remove Go dependencies with go get and go mod tidy, and what the no required module provides package error means.
Adding a library to a Go project takes two things: an import in your code and a matching entry in go.mod. The go get and go mod tidy commands keep those two in sync.
Adding a Dependency
Write the import first:
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
fmt.Println(len(uuid.NewString()))
}
Building now fails, because go.mod does not list the module yet:
main.go:6:2: no required module provides package github.com/google/uuid; to add it:
go get github.com/google/uuid
The message tells you the fix. Either run go get for that one module, or let go mod tidy find everything missing:
go mod tidy
go: finding module for package github.com/google/uuid
go: downloading github.com/google/uuid v1.6.0
go: found github.com/google/uuid in github.com/google/uuid v1.6.0
go.mod now contains require github.com/google/uuid v1.6.0, go.sum has its checksums, and go run . prints 36, the length of a UUID string.
What go mod tidy Does
go mod tidy makes go.mod and go.sum match the imports in your code:
- adds modules for imports that are missing
- removes modules that nothing imports any more
- adds missing
go.sumentries and removes unneeded ones - marks indirect dependencies with
// indirect
Run it after adding or removing imports, and before committing.
go get does not remove anything:
Deleting an import does not remove the module from go.mod. Only go mod tidy does that. Projects that never run it collect old dependencies over time.
go get for Specific Versions
go get is for choosing which version of a module to use:
go get github.com/google/uuid@latest # newest release
go get github.com/google/uuid@v1.5.0 # exact version (can downgrade)
go get github.com/google/uuid@none # remove the requirement
go get -u ./... # update all direct and indirect deps to newer minor/patch
Downgrading prints a message such as go: downgraded github.com/google/uuid v1.6.0 => v1.5.0.
go get no longer installs programs:
Since Go 1.17, go get only manages dependencies in go.mod. To install a command-line tool, use go install example.com/tool@latest. Old tutorials that say go get -u some/tool to install it are out of date.
Listing Dependencies
go list -m all # every module in the build, with versions
go list -m -u all # same, plus available updates in [brackets]
go mod why github.com/google/uuid # which import chain needs it
go mod graph # full requirement graph
go mod why is the answer to "why is this module in my go.mod?".
Vendoring
go mod vendor copies all dependencies into a vendor/ folder in your project. Builds then use that folder instead of the module cache. Some teams use it for builds without network access or to review dependency code in pull requests. It is optional, most projects do not vendor.
Version control and go.sum:
Forgetting to commit go.sum makes builds on other machines fail with missing go.sum entry. Always commit both files after go mod tidy.
Clean dependencies:
go mod tidy changes nothing, go build ./... and go test ./... pass, and go list -m -u all shows you which updates are available when you choose to take them.
Summary
Import a package, then run go mod tidy to add it to go.mod and go.sum, or go get module@version to pick a specific version. go mod tidy also removes unused dependencies, so run it before each commit. Use go list -m all and go mod why to inspect dependencies, go install to install tools, and commit both module files.