Learn Go← Dashboard

Install Go, write hello world, understand go run vs go build.

Go Modules & go.mod

A module is a project. It's a folder with a go.mod file at the top, which tells the compiler:

  • the module's path (its import name)
  • the Go version it targets
  • every dependency and its exact version

You'll work with modules from day one. They replace the older GOPATH workflow that existed before Go 1.11.

Starting a module

mkdir hello && cd hello
go mod init example.com/hello

That creates a single file:

// go.mod
module example.com/hello

go 1.23

The path can be anything you want — but pick something that uniquely identifies you, typically a domain or git URL like github.com/yourname/project.

Adding a dependency

go get github.com/google/uuid

Two things happen:

  1. go.mod gets a require github.com/google/uuid v1.x.y line.
  2. A go.sum file is created (or updated) — it pins cryptographic hashes of the dependency's contents so nobody can swap the code under you.

After the go get, go.mod looks like:

module example.com/hello

go 1.23

require github.com/google/uuid v1.6.0

You don't edit go.sum by hand. Treat it like a lockfile.

go playground
Loading...

Useful module commands

| Command | What it does | | ------------------ | ----------------------------------------------------- | | go mod init PATH | Start a new module. | | go get PKG | Add or upgrade a dependency. | | go mod tidy | Remove unused deps and add missing ones. | | go mod download | Download deps without building. | | go mod why PKG | Explain why this dependency exists. | | go mod graph | Print the dep graph. |

Versioning rule of thumb

Go modules follow semantic versioning strictly:

  • v0.x.y — unstable, anything can change.
  • v1.x.y — stable; minor and patch versions never break callers.
  • v2.x.y and above — must have /v2 (or /v3, …) appended to the import path. This is a one-off rule unique to Go and it prevents accidental upgrades.
import "github.com/some/pkg/v2"

Minimum Version Selection

When two dependencies require different versions of the same library, Go does not pick "the latest". It picks the minimum version that satisfies every requirement in the graph. This is called MVS. The upshot: builds are reproducible without a lockfile resolver, and adding a dependency rarely cascades into surprise upgrades.

If you want a newer version, ask for it explicitly: go get pkg@v1.5.0.

What's the purpose of `go.sum`?
You depend on `lib v1.2.0`, your dependency depends on `lib v1.4.0`. Which version does Go build with?