← thecodex.expert · The Codex Family of Knowledge
Go

Setup and Tooling

One download gives you the compiler, the standard library, and every tool you need — no separate package manager or build system to install.

Go 1.26 go.mod & modules Last verified:
Where this bites you

A single-file program runs fine with go run main.go even with no go.mod anywhere in sight, so it's easy to conclude modules are optional for a small project. Then the code grows past one file, and the natural next command — go run ., telling Go to run "whatever's in this directory" instead of naming files one by one — refuses to work, with an error that gives no hint that the previous command ever succeeded without a module.

Goterminal
$ go run main.go        // single file, no go.mod anywhere -- works fine
hello

$ go run main.go greet.go   // still no go.mod -- naming files explicitly still works
hello

$ go run .                  // the natural next command once there's more than one file
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
Canonical Definition

Installing Go means downloading a single toolchain from go.dev that bundles the compiler, the standard library, and the go command — the one CLI used to build, run, test, format, and manage dependencies for every Go project. Since Go 1.11, projects are organized around a go.mod file (Go Modules) rather than the older GOPATH convention, meaning code can live in any folder rather than a single fixed workspace.

Installing Go

Go is distributed as a single package from go.dev/dl for Windows, macOS, and Linux, plus package-manager options (brew install go, apt install golang-go, etc.). After installing, go version confirms the toolchain is on your PATH. Unlike languages that separate the compiler from the package manager (Python + pip, Node + npm), Go ships both in one binary.

Goterminal
$ go version
go version go1.26.0 darwin/arm64

$ mkdir hello && cd hello
$ go mod init example.com/hello   // creates go.mod, names the module
$ echo 'package main

import "fmt"

func main() { fmt.Println("hello") }' > main.go

$ go run main.go
hello

Naming a file explicitly (go run main.go) runs in a module-free "file mode" that works with no go.mod at all — which is exactly what made the bug above possible. Running a directory instead (go run ., or go build ., or go test) always resolves as a package inside a module, so it always needs one. The fix is the go mod init step shown above — run once, it's permanent for the rest of the project's life:

Goterminal
$ go mod init example.com/hello   // run once, anywhere in the project's life
go: creating new go.mod: module example.com/hello

$ go run .                        // now resolves as a module -- works permanently
hello

Modules vs. the old GOPATH

Before Go 1.11 (2018), every Go project had to live inside a single global $GOPATH/src directory, and dependencies were fetched into that same shared tree — a frequent source of version conflicts. Go Modules replaced this: a go.mod file at the root of a project declares its module path and dependency versions, and the project can live anywhere on disk. A companion go.sum file records cryptographic checksums of every dependency, so builds are reproducible. Modules have been the default and recommended approach since Go 1.16 (2021); GOPATH mode still exists but is rarely used in new code.

The go command's everyday subcommands

A handful of go subcommands cover almost all daily work: go run compiles and immediately runs a program without leaving a binary behind; go build compiles a binary; go test runs any function named TestXxx in _test.go files; go fmt rewrites source files to Go's one canonical formatting style (removing an entire category of style debates); and go get adds or updates a dependency in go.mod. Because formatting is enforced by tooling rather than convention, virtually all Go code in the wild looks the same.

Sources

1
The Go Authors. go.dev/doc/install and go.dev/ref/mod — official install guide and the Go Modules Reference.