thecodex.expert · The Codex Family of Knowledge
Go

Modules and Dependencies

A module’s major version 2 or higher must be baked into its import path — a deliberate, sometimes surprising rule that avoids version-conflict ambiguity.

Go 1.26 Semantic import versioning Last verified:
Canonical Definition

Go Modules resolve dependencies using semantic versioning (vMAJOR.MINOR.PATCH) and Minimal Version Selection, which picks the lowest version that satisfies every dependency’s stated requirement rather than always grabbing the newest. Every dependency’s exact version and cryptographic checksum is locked in go.sum, so a build is reproducible even if the upstream package changes later. Go additionally requires “semantic import versioning”: a module at major version 2 or above must append /v2 (or /v3, etc.) to its module path, so that two incompatible major versions of the same module can be imported side by side without conflict.

go.mod and go.sum

go.mod declares the module's own path, its Go version, and its direct/indirect dependencies with version constraints. go.sum records a cryptographic hash for every dependency (and every version ever resolved), so go build can verify nothing was tampered with since it was first fetched.

Gogo.mod
module github.com/you/myapp

go 1.26

require (
    github.com/gin-gonic/gin v1.10.0
    golang.org/x/crypto v0.28.0
)

Updating and adding dependencies

go get adds or upgrades a dependency and updates go.mod/go.sum automatically; go mod tidy reconciles both files with what the code actually imports, adding anything missing and removing anything unused.

Goterminal
$ go get github.com/gin-gonic/gin@v1.10.0    // add/pin a specific version
$ go get -u ./...                             // upgrade all dependencies
$ go mod tidy                                 // clean up go.mod/go.sum to match actual usage

The /v2 rule for major versions 2+

Under Go's semantic import versioning, only major version 0 or 1 use a plain module path. From major version 2 onward, the module's path itself must end in /v2, /v3, and so on — baked into both go.mod and every import statement. This lets a program depend on both an old and a new incompatible major version of the same library simultaneously (as different Go packages, since their import paths differ), which is useful during a slow, module-by-module migration.

Gov2_import.go
import (
    "github.com/some/library"      // v0 or v1
    libv2 "github.com/some/library/v2"   // v2+: /v2 is part of the import path
)

Sources

1
The Go Authors. Go Modules Reference, go.dev/ref/mod, and "Go Modules: v2 and Beyond", go.dev/blog/v2-go-modules.