gofmt, go vet and the Standard Toolchain
gofmt settles formatting for everyone, go vet finds mistakes the compiler allows, and go doc reads package documentation offline.
gofmt -l -w . | go vet ./... | go doc <package>[.<Name>]Go ships one set of tools with the language, and effectively every project uses them unchanged. That is the point: layout, checking and documentation are not decisions each team makes again.
gofmt
gofmt rewrites a Go file into the one standard layout. Tabs for indentation, fixed brace placement, sorted imports. There are no style options, so review time is never spent on them. gofmt -l . lists files that are not formatted. gofmt -w . rewrites them in place. go fmt ./... is a shorthand that runs gofmt -l -w over the packages you name, and ./... means this directory and everything under it. Most editors run gofmt when you save, which is the right setting.
go vet
The compiler rejects code that cannot work. go vet reports code that compiles but is probably wrong: a Printf placeholder that does not match its argument, a lock copied by value, a result that can never be reached. Run go vet ./... before you commit. go test already runs a subset of these checks for you.
go doc
go doc strings prints a package's documentation in your terminal, offline, from the source on your disk. go doc strings.TrimSpace prints one function's signature and comment. Documentation is just the comment above a declaration, so it cannot drift away from the code it describes.
go help lists the rest. Since Go 1.24, go.mod can record tool dependencies on a tool line, and go tool <name> runs them at the version the module pins.
Example
// Package main is laid out the way gofmt produces: tabs, one grouped import block.
package main
import (
"fmt"
"strings"
)
// greet returns a greeting for name. A comment above a declaration is its documentation,
// which is what go doc prints.
func greet(name string) string {
// TrimSpace removes spaces from both ends of the text.
return fmt.Sprintf("hello, %s", strings.TrimSpace(name))
}
func main() {
// %s expects text. go vet checks that placeholders and arguments agree.
fmt.Printf("%s\n", greet(" world "))
}
// Output:
// hello, world
When to use it
- Stop a pull request from mixing real changes with formatting churn.
- Catch a mismatched Printf placeholder before it reaches a log file in production.
- Look up a standard library function's exact signature with no network connection.
More examples
A bug the compiler allows and go vet catches
Run go vet ./... on this and it reports: fmt.Printf format %d has arg "world" of wrong type string. This is exactly the class of mistake vet exists for — code that builds, ships, and then prints nonsense into a log. Run vet in CI so nobody has to notice it by eye.
package main
import "fmt"
func main() {
// %d is for whole numbers, but "world" is text.
// This compiles and runs. The output is wrong, not the build.
fmt.Printf("hello, %d\n", "world")
}
// Output:
// hello, %!d(string=world)
Formatting as a build step
The last line is the usual CI check: gofmt -l prints nothing when everything is formatted, so test -z succeeds only then. Pair it with go vet ./... and go build ./... for a three-line pipeline that catches layout drift and likely bugs before review.
$ gofmt -l . # lists unformatted files, prints nothing when all are clean
main.go
$ gofmt -w . # rewrite them in place
$ test -z "$(gofmt -l .)" # fails if anything is still unformattedReading documentation from the terminal
go doc reads the source already on your disk, so it works offline and always matches the version you are building against. -all is how you survey an unfamiliar package, and -src is how you answer "what does it actually do" when the comment is not enough.
$ go doc strings.TrimSpace
package strings // import "strings"
func TrimSpace(s string) string
TrimSpace returns a slice (substring) of the string s, with all leading and
trailing white space removed, as defined by Unicode.
$ go doc -all net/http | less # every exported name in a package
$ go doc -src strings.TrimSpace # the source as well as the comment
Discussion