Go

What is semantic import versioning, and why must v2+ modules change their import path?

Question 409MediumGo 1.22 to 1.25

The import compatibility rule says: if an old package and a new package have the same import path, the new one must be backward compatible with the old one. A major version bump breaks compatibility, so from v2 onward the major version becomes part of the module path: module github.com/acme/lib/v2, and importers write import "github.com/acme/lib/v2/client".

Because of this, v1 and v2 are different modules. They can coexist in one build, which lets a large codebase migrate step by step and avoids diamond-dependency deadlock. v0 and v1 have no suffix. v0 has no compatibility promise at all.

import (
    lib   "github.com/acme/lib/client"    // v1.x
    libv2 "github.com/acme/lib/v2/client" // v2.x, separate module
)

Gotchas: tagging v2.0.0 without changing the module line makes the go command reject the version (or treat it as +incompatible if the repo has no go.mod). Package-level state such as registries or global flags is duplicated when both majors are linked into one binary.

More on Modules, Packages & Tooling

All 36 Modules, Packages & Tooling questions