One of the best things about Go is that the tooling is built in. Compiler, test runner, formatter, doc viewer, dependency manager — all one go command. No webpack, no Babel, no debates about which formatter to use.
In simple language: in most languages we bolt on a dozen separate tools; in Go they come in the box.
The everyday commands
go run main.go # compile + run in one step (great for scripts/dev)
go build # compile to a binary, no run
go test ./... # run all tests recursively
go install # build and drop the binary in $GOPATH/bin
go build produces a single static binary with no runtime dependencies — we copy that one file to a server and it just runs. That’s why Go is so popular for containers and CLIs.
Formatting — there’s only one true format
gofmt (and its wrapper go fmt) formats our code into the one canonical Go style. Tabs, spacing, alignment — all decided for us. There are no style debates in Go because there’s literally one accepted format.
go fmt ./... # format all files in the module
gofmt -d file.go # show what WOULD change (diff), don't write
Most teams run gofmt on save. goimports is the popular upgrade — it does everything gofmt does plus automatically adds and removes import statements for us.
goimports -w main.go # format AND fix imports, write in place
go vet — catch suspicious code
go vet is a built-in static checker. It doesn’t check style (that’s gofmt’s job) — it flags likely bugs: a Printf with the wrong number of arguments, an unreachable line, a struct tag typo, a lock copied by value.
go vet ./... # report suspicious constructs
Think of it as a free, fast first-pass bug catcher. It runs automatically as part of go test, too.
Managing dependencies
Dependencies are handled by Go modules. The two commands we lean on:
go get github.com/some/pkg # add or upgrade a dependency
go mod tidy # add missing deps + remove unused ones
go mod tidy is the housekeeper — after we add or delete imports, it syncs go.mod and go.sum so they exactly match what the code actually uses. Run it before committing.
Reading docs and generating code
go doc fmt.Println # print docs for a function, right in the terminal
go doc -all strings # full docs for a whole package
go generate ./... # run //go:generate directives in the code
go doc reads the doc comments straight from source — no internet needed. go generate runs commands we’ve annotated in comments (//go:generate ...), commonly used to produce mocks or stringer methods. It’s not automatic; we run it ourselves.
The popular linters (third-party)
The standard tools cover a lot, but two community linters go further:
- staticcheck — a deep static analyzer that catches many subtle bugs and dead code
go vetmisses. - golangci-lint — a fast meta-linter that bundles staticcheck,
go vet, and dozens of others behind one config. This is the de-facto CI standard in most Go shops.
golangci-lint run ./... # run the whole linter bundle
These aren’t built in, but every serious team installs golangci-lint. Worth name-dropping in an interview.
Interview soundbite
Go’s toolchain is built in — one go command does build, run, test, fmt, vet, doc, and module management, and go build spits out a single static binary. gofmt enforces one canonical format so there are no style arguments, goimports also fixes imports, go vet catches likely bugs, and go mod tidy syncs dependencies. The popular third-party linters are staticcheck and golangci-lint, the CI standard.