Semantic versioning (semver)
Semantic versioning is the package-versioning convention MAJOR.MINOR.PATCH where MAJOR is incremented for breaking changes, MINOR for backwards-compatible feature additions, and PATCH for backwards-compatible bug fixes. The convention lets consumers express dependency tolerance — '^1.2.3' accepts any 1.x.x ≥ 1.2.3 but rejects 2.0.0.
Semver's promise is broken constantly in practice: bug fixes inadvertently introduce breaking behaviour, new features rely on deprecated APIs the consumer was using, and patch releases ship without changelogs. The pragmatic adaptation: pin tightly (exact versions or '~' patch-only ranges), automate upgrades via Dependabot/Renovate, and rely on test coverage to catch the semver violations. The 'caret' range ('^') is the npm default but is risky for libraries you don't control — many ecosystems have moved toward stricter pinning in production code, leaving semver ranges only for libraries you publish.
Discussed in our use-cases
ICP-targeted pages where semantic versioning (semver) is part of the framing.
Related terms
- Lockfile
A lockfile records the exact resolved version of every package in a dependency tree — direct and transitive — so any subsequent install reproduces the same versions.
- Dependency pinning
Dependency pinning fixes the exact version of every dependency (and transitively, every transitive dependency) so the same source produces the same build artefact regardless of when or where it's built.
- Breaking change
A breaking change is any change to a published interface (API endpoint, library function signature, CLI flag, configuration key) that requires consumer code or configuration changes to keep working.