How it works
The explanation, with examples you can run.
go.mod
module example.com/shop go 1.24.0 require ( github.com/google/uuid v1.6.0 golang.org/x/sync v0.10.0) tool golang.org/x/tools/cmd/stringermoduleis the path other code imports. For public code it is usually where the repository lives.gois the minimum Go version. It also selects language semantics: a module that saysgo 1.22or later gets a new loop variable per iteration, for example.requirelists minimum versions. Since Go 1.17 indirect dependencies are listed too (marked// indirect), so the go command can load a smaller module graph.tool(Go 1.24+) records a command-line tool you run withgo tool stringer. It replaces the oldtools.gofile with blank imports.
go mod tidy adds what your imports need and drops what they don't. go get pkg@v1.7.0 changes one requirement.
How versions are chosen
Go uses minimal version selection. It walks the requirement graph and, for each module, takes the highest version that anything in the graph requires. It never picks a newer release on its own. A new upstream release cannot change your build until somebody edits a go.mod, which is why Go has no separate lock file: go.mod already decides the versions, and go.sum locks their contents.
Major versions follow semantic import versioning: from v2 on, the major version is part of the path (example.com/lib/v2). A program can import v1 and v2 at once, because they are different modules.
Where code comes from
By default modules are downloaded through https://proxy.golang.org, falling back to the source repository (GOPROXY=https://proxy.golang.org,direct). Each new hash is checked against sum.golang.org, a public, append-only log, so a dependency can't be quietly replaced. For private code, set GOPRIVATE=corp.example.com/*: matching modules are fetched directly and not looked up in the public log.
The toolchain is a dependency too
Since Go 1.21, if go.mod says go 1.27.0 and your installed go is older, the default GOTOOLCHAIN=auto makes it download that toolchain (itself a module) and run it. An optional toolchain line names a preferred newer version for work inside the module. Set GOTOOLCHAIN=local to forbid switching; the build then fails instead. Some repackaged Go distributions change this default, and go env GOTOOLCHAIN shows the value in effect.
Workspaces
To work on two modules together without editing replace lines, go work init ./shop ./lib creates a go.work file that makes the go command use your local copies. Usually it is not committed.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.