Coding

Semantic Versioning, Decoded

Semantic Versioning, Decoded

Cover: Semantic Versioning, Decoded

Version numbers like 2.4.1 aren't arbitrary — under semantic versioning (semver), each of the three numbers is a specific promise to anyone depending on your code.

The three positions

MAJOR . MINOR . PATCH
  2   .  4   .  1
  • PATCH (2.4.1) — bug fixes only. Nothing about how the code is used changes.
  • MINOR (2.4.1) — new functionality added, but nothing existing breaks. Old code keeps working.
  • MAJOR (2.4.1) — breaking changes. Code written against the old version might not work anymore without changes.

Why this matters for dependencies

When your package.json specifies ^2.4.1, the caret tells the package manager "any version that stays within MAJOR version 2 is safe to auto-install." That promise only holds if the package author actually follows semver — which is why a MINOR release that accidentally breaks something is worse than a bug: it breaks the entire trust model every downstream project relies on.

Reading the common version-range symbols

  • ^2.4.1 — compatible with 2.x.x, won't auto-upgrade to 3.0.0.
  • ~2.4.1 — compatible with 2.4.x only, won't even take 2.5.0.
  • 2.4.1 (exact) — pinned, no automatic updates at all.
The practical takeaway: before upgrading a MAJOR version, actually read the changelog. Before shipping one yourself, ask honestly whether you just broke someone's existing code — if yes, it's a MAJOR bump, not a MINOR one, no matter how small the change felt.

Comments