The go tool
Go ships as a single go binary that builds, tests, formats, generates, documents, and profiles. Every subcommand, with its flags and a worked example.
One binary does the whole job: compiling, running, testing, formatting, dependency management, documentation, and profiling. There is no separate build tool, formatter, or package manager to install.
Click any command for its flags and a worked example, or filter to jump straight to one.
Build and run
4- go run <pkg|file...>$
go run .Compiles and runs a program, leaving no binary behind.
Builds into a temporary directory and executes the result. Arguments after the package go to the program, not to the go tool:go run . -port 9000passes-port 9000through.Flags-raceEnable the data race detector.-tagsComma-separated build tags to satisfy. - go build [pkg...]$
go build -o bin/app .Compiles packages into a binary without running it.
Writes the binary into the current directory, named after the module or directory, unless-osays otherwise. Building a non-main package compiles it and discards the result, which makesgo build ./...a fast whole-repo compile check.Flags-oWrite the binary to this path.-raceEnable the data race detector.-ldflagsPass flags to the linker, commonly -ldflags="-X main.version=1.2.3".-trimpathStrip local filesystem paths out of the binary. - go install <pkg>[@version]$
go install golang.org/x/tools/cmd/stringer@latestBuilds a command and puts the binary in GOBIN.
With an@versionsuffix it installs without touching the current module'sgo.mod, which is how you install a tool. Without one it installs from the current module. The binary lands inGOBIN, orGOPATH/binwhen that is unset. - go clean$
go clean -cache -testcacheRemoves object files and cached build artifacts.
Flags-cacheEmpty the whole build cache.-testcacheExpire cached test results.-modcacheDelete the downloaded module cache.
Test and check
4- go test [pkg...]$
go test ./...Builds and runs the tests in each named package.
Results are cached. A second run of an unchanged package prints(cached)instead of running anything, and-count=1is the documented way to force a real run.Flags-vPrint each test name and its log output.-runRun only tests whose name matches this regular expression.-coverReport statement coverage.-raceEnable the data race detector.-benchRun benchmarks matching this regular expression.-count=1Bypass the test cache.terminalok example.com/hello 0.002s ok example.com/hello/store (cached) - go vet [pkg...]$
go vet ./...Reports suspicious constructions the compiler accepts.
Catches mistakes that compile: aPrintfverb that does not match its argument, a struct tag that will not parse, a lock copied by value, an unreachable return. It runs automatically as part ofgo test.terminal./main.go:8:2: fmt.Printf format %s has arg count of wrong type int - go fix [pkg...]$
go fix ./...Rewrites code that uses old APIs to the current ones.
Applies the same rewritesgo tool fixknows about. It edits files in place, so commit first. - go bug$
go bugOpens a browser to file a Go issue, with your environment filled in.
Format and generate
3- go fmt [pkg...]$
go fmt ./...Formats the source in each named package and prints what it changed.
A wrapper that runsgofmt -l -wover the package's files. Go has one canonical layout and no configuration for it: indentation is tabs, alignment is spaces, and neither is a preference. Editors normally run this on save, so a repository wherego fmt ./...prints nothing is the normal state.
Usegofmtdirectly when you want the options the wrapper does not expose, such as-dto see a diff without writing.terminalmain.go internal/store/store.go - gofmt -l -d <path>$
gofmt -l -d .Lists unformatted files and prints the diff, changing nothing.
The form to use in CI.-llists the files that need formatting,-dprints the diff, and neither writes. A non-empty output means the build should fail.Flags-lList files whose formatting differs.-wWrite the result back to the file.-dPrint a diff instead of the formatted file.-sSimplify code where it can. - go generate [pkg...]$
go generate ./...Runs the commands named in //go:generate comments.
Scans for lines of the form//go:generate command argsand runs each one in the directory of the file that holds it. Nothing runs automatically:go buildandgo testnever trigger it, so generated files are committed and regenerated deliberately.
The comment has no space after//.// go:generateis an ordinary comment and is silently ignored.Flags-nPrint the commands without running them.-xPrint each command as it runs.-runOnly run commands matching this regular expression.terminal// status.go //go:generate stringer -type=Status type Status int $ go generate ./... $ ls status.go status_string.go
Documentation and environment
4- go doc [pkg][.<name>]$
go doc bufio.ScannerPrints the documentation for a package, type, function, or method.
The fastest way to answer "what does this return" without leaving the terminal. It reads the source on your machine, so the version it describes is the version you are compiling against.
The argument narrows as you add to it: a package name gives the summary, a dotted name gives one symbol, and a second dot reaches a method on a type.Flags-allPrint all documentation for the package, not just the summary.-srcShow the source code of the symbol.-uInclude unexported identifiers.-cMatch the symbol name case-sensitively.terminal$ go doc bufio # the package summary $ go doc bufio.Scanner # one type $ go doc bufio.Scanner.Scan # one method on it $ go doc -src bufio.NewScanner $ go doc net/http.Client # full import path when ambiguous $ go doc bufio.Scanner.Scan package bufio // import "bufio" func (s *Scanner) Scan() bool Scan advances the Scanner to the next token, which will then be available through the Scanner.Bytes or Scanner.Text method. It returns false when there are no more tokens, either by reaching the end of the input or an error. - go version [-m <binary>]$
go version -m ./appPrints the Go version, or the versions built into a binary.
-mreads the module information embedded in a compiled binary, including every dependency version. It works on any Go binary, which makes it the quickest way to audit something you did not build.terminalgo version go1.26.1 linux/amd64 - go env [-w] [var...]$
go env GOMODCACHEPrints the Go environment, or sets a value with -w.
Naming variables prints only those, one per line, which is what makes it usable in a script.-wwrites a persistent default into the user's env file, and-uremoves it again.Flags-wSet a variable persistently.-uUnset a variable previously set with -w.-jsonPrint the whole environment as JSON.terminal$ go env GOMODCACHE /home/you/go/pkg/mod - go list [pkg...]$
go list -m -u allReports information about packages and modules.
The scriptable view of everything the tool knows.-ftakes atext/template, so you can print any field of the package or module struct.Flags-mList modules instead of packages.-uAdd available upgrades to the module listing.-jsonPrint the full record as JSON.-fFormat each record with a text/template.terminal$ go list -f '{{.ImportPath}} {{.GoFiles}}' ./... example.com/hello [main.go]
Modules and dependencies
9- go mod init <module-path>$
go mod init example.com/helloCreates a go.mod file in the current directory.
The module path is the string other code will import, so it is normally the repository URL. It is not a filesystem path and does not have to resolve while you are developing. - go mod tidy$
go mod tidyAdds missing module requirements and drops unused ones.
Reads every import in the module and reconcilesgo.modandgo.sumagainst them. It is the command to run after adding or deleting an import, and the one CI should check leaves no diff.terminalgo: finding module for package github.com/gofiber/fiber/v3 go: found github.com/gofiber/fiber/v3 in github.com/gofiber/fiber/v3 v3.4.0 - go get <pkg>[@version]$
go get github.com/jackc/pgx/v5@v5.10.0Adds, upgrades, or removes a dependency in go.mod.
Since Go 1.17 this only edits dependencies; installing a tool binary isgo install. The version suffix takes a tag, a branch, a commit,@latest, or@noneto remove the dependency.Flags-uUpgrade to the latest minor or patch release.-u=patchUpgrade to the latest patch release only. - go mod download [modules]$
go mod downloadDownloads modules into the local module cache.
Useful as its own Docker layer: copygo.modandgo.sum, download, then copy the source, so a code change does not re-fetch every dependency. - go mod verify$
go mod verifyChecks that cached dependencies match the hashes in go.sum.
terminalall modules verified - go mod why <pkg>$
go mod why golang.org/x/textExplains why a package or module is needed.
Prints the shortest import chain from a package in the main module to the one you named, which is how you find out who pulled in a dependency you did not add. - go mod graph$
go mod graphPrints the module dependency graph, one edge per line.
- go mod edit <flags>$
go mod edit -replace=old.dev/x=../xEdits go.mod from a script, without a text editor.
Flags-requireAdd or update a requirement.-replacePoint a module path at another module or a local directory.-droprequireRemove a requirement.-goSet the go directive's language version. - go mod vendor$
go mod vendorCopies every dependency into a vendor directory.
Oncevendor/exists the tool builds from it by default, ignoring the module cache.-mod=modoverrides that for one command.
Workspaces
3- go work init [dirs...]$
go work init ./api ./workerCreates a go.work file covering several modules at once.
A workspace lets modules in different directories see each other's local changes with noreplacedirective in anygo.mod.go.workis a local development file and is normally left out of version control. - go work use [dirs...]$
go work use ./billingAdds a module directory to the workspace.
- go work sync$
go work syncPushes the workspace's resolved versions back into each module's go.mod.
Tools and diagnostics
5- go tool [name] [args]$
go tool pprof cpu.outRuns one of the tools shipped with the toolchain.
With no arguments it lists what is available. Since Go 1.24 it also runs tools declared in the module'sgo.modwith atooldirective, which is how a project pins its own linters and generators.terminal$ go tool addr2line asm buildid cgo compile covdata cover dist distpack doc fix link nm objdump pack pprof test2json trace vet - go tool pprof <profile>$
go tool pprof -http=:8081 cpu.outOpens a CPU, memory, or block profile for analysis.
-httpserves an interactive flame graph in the browser rather than dropping into the terminal prompt. Produce the profile withgo test -cpuprofile cpu.outor thenet/http/pprofhandlers. - go tool trace <trace file>$
go tool trace trace.outOpens an execution trace, showing goroutines and the scheduler.
- go tool cover <flags>$
go tool cover -html=cover.outRenders a coverage profile as annotated source.
Pairs withgo test -coverprofile=cover.out. The HTML view colors every statement by whether a test reached it. - go telemetry <on|off|local>$
go telemetry offControls whether the toolchain uploads usage telemetry.
Off by default: nothing is uploaded unless you opt in.localkeeps counters on disk without sending them, andoffstops collection entirely.