go install pkg@version: Install Tools in CI
go install <package>@<version> downloads, builds, and installs a command at a pinned version into $GOBIN (or $GOPATH/bin), without touching your module's go.mod.
Since Go 1.16, installing a tool requires a version suffix. Pinning it makes CI tool installs reproducible, the way cargo install --locked does for Rust.
What it does
go install builds the named main package at the requested version in module-aware mode and places the binary in $GOBIN (or $GOPATH/bin, default ~/go/bin). The @version can be a tag, a commit, latest, or a pseudo-version. It does not modify the current module's go.mod.
Common usage
go install golang.org/x/tools/cmd/stringer@latest
go install github.com/golang/mock/mockgen@v1.6.0
GOBIN=/usr/local/bin go install honnef.co/go/tools/cmd/staticcheck@2024.1.1Flags
| Item | What it does |
|---|---|
| pkg@v1.2.3 | Install an exact tagged version |
| pkg@latest | Install the latest released version |
| pkg@<commit> | Install at a specific commit (pseudo-version) |
| GOBIN=<dir> | Env: where to place the installed binary |
| -x | Print the build commands |
In CI
Always pin a real version, not @latest, so the toolchain is reproducible. Set GOBIN to a directory on PATH and cache both ~/go/bin and the module cache to skip rebuilds. Installing tools this way keeps them out of your project go.mod, unlike adding a tool dependency.
Common errors in CI
"go install: version is required when current directory is not in a module" or "go install pkg: ... to install ... add a version like @latest" means you omitted the @version suffix. "package ... is not a main package" means you pointed at a library, not a command. "no matching versions for query "latest"" means the module has no released version or the path is wrong.