goenv
Go version manager — install, switch, and manage multiple Go versions side by side.
Installation
go install github.com/hitzhangjie/goenv@latest
Ensure $GOPATH/bin (or $GOBIN) is in your PATH. Also add ~/.goenv/bin to your PATH so wrapper scripts are discoverable:
export PATH="$HOME/.goenv/bin:$PATH"
Commands
goenv versions — list available Go versions
Fetch and display all available Go versions from the golang/go GitHub repository, grouped by major.minor version.
goenv versions
Results are cached to ~/.goenv/versions.json. On subsequent runs, you'll be asked whether to refresh from GitHub.
Flags:
| Flag |
Description |
--update |
Force refresh from GitHub, bypassing the interactive prompt |
--min-version <v> |
Only show versions >= v (e.g., go1.22) |
--min-year <n> |
Only show versions from year >= n (e.g., 2020) |
--all |
Fetch all versions, ignoring any filter |
Examples:
# List all versions (from cache if available)
goenv versions
# Force refresh from GitHub, show versions >= go1.22
goenv versions --update --min-version go1.22
# Show versions from 2020 onward
goenv versions --min-year 2020
The GitHub API has rate limits for unauthenticated requests. Set GITHUB_ACCESS_TOKEN to raise the limit:
export GITHUB_ACCESS_TOKEN=ghp_xxxxxxxxxxxx
goenv install <version> — install a Go version
Download and install a specific Go version. The tarball is fetched from https://dl.google.com/go/ and extracted to ~/.goenv/sdk/.
goenv install go1.22.1
The go prefix is optional — both forms work:
goenv install 1.22.1
What it does:
- Detects your OS and architecture via
go env GOOS / go env GOARCH
- Downloads the tarball to
~/.goenv/downloads/ (skips if already downloaded)
- Extracts the SDK to
~/.goenv/sdk/go<version>/
- Creates a wrapper script at
~/.goenv/bin/go<version> that sets per-version GOROOT, GOPATH, GOBIN, GOCACHE, and GOTESTCACHE
- Creates a
~/.goenv/bin/gofmt<version> wrapper for gofmt
goenv list — list installed versions
Show all locally installed Go versions.
goenv list
goenv fix — regenerate wrapper scripts
Regenerate wrapper scripts for all installed Go versions. Useful after updating goenv itself to pick up changes in environment variable settings.
goenv fix
goenv cleanup — clean up downloads
Remove all downloaded tarballs from ~/.goenv/downloads/ to free disk space.
goenv cleanup
Usage
After installation, invoke a specific Go version by its wrapper script name:
# Run go 1.22.1
go1.22.1 version
# Build with go 1.21.0
go1.21.0 build ./...
# Run gofmt for the same version
gofmt1.22.1 -w .
Each wrapper script sets GOROOT, GOPATH, GOBIN, GOCACHE, and GOTESTCACHE scoped to that version — no environment pollution, and no interference between versions.
Directory layout
~/.goenv/
├── bin/ # Wrapper scripts (add this to PATH)
│ ├── go1.22.1
│ ├── gofmt1.22.1
│ ├── go1.21.0
│ └── gofmt1.21.0
├── downloads/ # Downloaded tarballs (safe to delete)
│ └── go1.22.1.darwin-arm64.tar.gz
├── sdk/ # Extracted Go SDKs
│ ├── go1.22.1/
│ └── go1.21.0/
├── go1.22.1/ # Per-version GOPATH
│ ├── bin/ # GOBIN
│ └── cache/ # GOCACHE
└── versions.json # Cached version list from GitHub
Environment variables
| Variable |
Purpose |
GITHUB_ACCESS_TOKEN |
GitHub personal access token for higher API rate limits when fetching versions |