Learn Go
intermediate2 min read

Modules

Go modules are the official dependency management system, introduced in Go 1.11 and made the default in Go 1.16. A module is a collection of related packages versioned together.

Initialising a Module

go mod init creates a go.mod file at the root of your project:

$ mkdir myapp && cd myapp
$ go mod init github.com/example/myapp

This creates:

// go.mod
module github.com/example/myapp

go 1.23

The module path (github.com/example/myapp) is the prefix for all package import paths within the module.

The go.mod File

go.mod records the module's dependencies:

module github.com/example/myapp

go 1.23

require (
    github.com/google/uuid v1.6.0
    golang.org/x/text v0.14.0
)

You never edit go.mod by hand for dependencies — use go get and go mod tidy.

Adding Dependencies

// main.go
package main
 
import (
    "fmt"
    "github.com/google/uuid"
)
 
func main() {
    id := uuid.New()
    fmt.Println(id.String())
}

Run go get to download and record the dependency:

$ go get github.com/google/uuid@v1.6.0

Go downloads the package, updates go.mod, and creates/updates go.sum.

The go.sum File

go.sum records cryptographic hashes of every module dependency. It ensures reproducible, tamper-proof builds:

github.com/google/uuid v1.6.0 h1:NIvaJDMnLl5AlHL5/Ljv9AFvs/GKiQ5/hkP1E7YUAk=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

Commit go.sum to source control alongside go.mod.

go mod tidy

go mod tidy adds missing requirements and removes unused ones:

$ go mod tidy

Run it regularly, especially after adding or removing import statements. In CI, verify go.mod and go.sum are in sync:

$ go mod tidy
$ git diff --exit-code go.mod go.sum

Semantic Versioning

Go modules follow Semantic Versioning: MAJOR.MINOR.PATCH.

The Minimum Version Selection (MVS) algorithm chooses the minimum version that satisfies all requirements, producing reproducible builds without a lock file.

Workspaces (go work)

Go 1.18 introduced workspaces for developing multiple modules together locally:

// go.work — created with: go work init ./moduleA ./moduleB
go 1.23
 
use (
    ./moduleA
    ./moduleB
)

Workspaces let you reference local module changes without publishing them first.

Useful Module Commands

go list -m all          # list all dependencies
go get pkg@version      # add or update a dependency
go get pkg@none         # remove a dependency
go mod tidy             # clean up go.mod and go.sum
go mod download         # download all modules to the cache
go mod verify           # verify cached modules match go.sum
go mod graph            # print the module dependency graph

Key Takeaways