The go Command

Go · Lesson 5 of 32 7 min read Updated

Most languages need a separate build tool, formatter, test runner and package manager. Go puts all of them into one program: the go command. Learning its main sub-commands makes you productive quickly, and the same commands work on every computer and in every company.

This lesson is a practical tour. Keep it open as a reference while you work through the rest of the course.

The commands you will use daily

CommandWhat it does
go run .Compile the package in this folder and run it
go buildCompile into an executable file
go test ./...Run all tests in the module
go fmt ./...Format all Go files
go vet ./...Report suspicious code
go mod tidyClean up go.mod and go.sum
go get pkg@versionAdd or upgrade a dependency
go install pkg@versionBuild and install a command-line tool
go doc nameShow documentation
go envShow Go settings

The pattern ./... means "this folder and every folder below it". So go test ./... tests the whole module, while go test . tests only the current package.

run and build

go run is for development: it compiles to a temporary place and runs the result. You can pass arguments to your program after the package:

Terminal
go run . Priya Jaipur

The program receives Priya and Jaipur in os.Args, which you will meet in Standard Library: os, io & time.

go build is for shipping. It creates an executable in the current folder. Add -o to choose the name and location:

Terminal
go build -o bin/shop.exe

Cross-compiling

A favourite Go feature: you can build for another operating system without installing anything extra. Two environment variables choose the target: GOOS (operating system) and GOARCH (processor). On Linux or macOS:

Terminal
GOOS=linux GOARCH=amd64 go build -o shop-linux
GOOS=windows GOARCH=amd64 go build -o shop.exe

In Windows PowerShell, set the variables first, then build:

PowerShell
$env:GOOS = "linux"
$env:GOARCH = "amd64"
go build -o shop-linux

This is how a developer on a Windows laptop builds a program for a Linux server in a data centre in Mumbai. Remember to remove the variables afterwards (Remove-Item Env:GOOS, Remove-Item Env:GOARCH) or close the window. Run go tool dist list to see every supported pair.

fmt and vet: clean and correct code

go fmt ./... rewrites your files in the standard Go layout. It prints the names of files it changed and nothing else.

go vet looks for code that compiles but is probably wrong. A classic example is a Printf verb that does not match its argument:

Go
package main

import "fmt"

func main() {
	stock := "five"
	fmt.Printf("%d packets left\n", stock)
}
Terminal
go vet ./...
Output
./main.go:7:2: fmt.Printf format %d has arg stock of wrong type string

The program would compile and print %!d(string=five) packets left, which is clearly a bug. go vet catches it before your users do. go test runs the most important vet checks automatically, so many bugs are reported during testing too.

install: getting tools

go install builds a command and puts the executable in the bin folder of your GOPATH (for example C:\Users\Kabir\go\bin). Add that folder to your PATH so you can run installed tools by name. Always include a version, usually @latest:

Terminal
go install golang.org/x/tools/gopls@latest

This is exactly how the VS Code extension installs gopls for you.

doc and env

go doc shows documentation without opening a browser. Give it a package or a package and a name:

Terminal
go doc strings.Repeat
go doc -all strings

The first command prints the signature func Repeat(s string, count int) string and its description. The second lists everything in the strings package. Go 1.27 also accepts a version, as in go doc example.com/pkg@v1.2.3.

go env prints settings. Ask for specific ones to keep it short:

Terminal
go env GOOS GOARCH GOVERSION
Output
windows
amd64
go1.27.3

fix: modernise old code

go fix was rebuilt in Go 1.26 as a home for modernizers: automatic rewrites that update old code to newer Go style. For example, it can replace interface{} with any, and replace a hand-written loop that searches a slice with slices.Contains.

Go
// before go fix
func hasCity(cities []string, c string) bool {
	for _, x := range cities {
		if x == c {
			return true
		}
	}
	return false
}
Go
// after go fix ./...
func hasCity(cities []string, c string) bool {
	return slices.Contains(cities, c)
}

Run go fix ./... on a clean Git working tree, then review the changes with git diff before committing. Go 1.27 added more modernizers, so it is worth running after each upgrade.

Common mistakes

  • Forgetting ./.... go test alone tests only the current folder; use go test ./... for the whole module.
  • go install without a version outside a module. Write @latest or a specific version, or the command fails.
  • Leaving GOOS set. After cross-compiling, a forgotten GOOS=linux makes every later go run build a Linux program that your Windows machine cannot start.
  • Ignoring go vet. It finds real bugs in seconds. Run it in every build script.

Key points

  • One go command handles building, running, testing, formatting, documentation and dependencies.
  • ./... means every package in this folder tree.
  • GOOS and GOARCH let you cross-compile for other systems with no extra setup.
  • go fmt formats, go vet finds suspicious code, and go fix modernises old code.
  • go install pkg@latest installs tools into GOPATH/bin.

Exercise

In any module you have created, run these commands and note what each one prints: go env GOOS GOARCH, go vet ./..., go fmt ./.... Then build a Linux executable named app-linux from your Windows or macOS machine and check that the file was created.

Show solution

On Windows PowerShell:

PowerShell
go env GOOS GOARCH
go vet ./...
go fmt ./...
$env:GOOS = "linux"; $env:GOARCH = "amd64"
go build -o app-linux
Remove-Item Env:GOOS; Remove-Item Env:GOARCH
Get-Item app-linux

go env prints your own system (for example windows and amd64). go vet and go fmt print nothing when the code is clean and already formatted. The app-linux file cannot run on Windows, but it runs on any 64-bit Linux machine.

Quick Quiz

1. What does ./... mean in go test ./...?

2. Which environment variables choose the target system when cross-compiling?

3. Which command reports a Printf verb that does not match its argument?

4. Where does go install place the built program by default?

Learn Go with a mentor

Free lessons get you started. Our Programming & Software Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call