Articles

What Is Semantic Versioning (SemVer)?

Semantic versioning encodes compatibility into a version number's three parts — major, minor, patch — so dependents know what a version bump might break.

Takina Takina · · 4 min read
A close-up of code representing version history

Semantic versioning, or SemVer, is a convention for structuring version numbers as MAJOR.MINOR.PATCH, where each segment communicates a specific kind of change. The point isn’t just organization — it’s a contract. A well-followed SemVer number tells anyone depending on your package, at a glance, whether upgrading is safe to do blindly or requires checking for breaking changes first.

The three segments

Given a version like 2.4.1:

  • MAJOR (2) — incremented for breaking changes. Anything that could break existing code depending on the package bumps this segment, and resets minor and patch back to zero.
  • MINOR (4) — incremented for new, backward-compatible functionality. New features, new optional parameters, new exports — anything additive that doesn’t break existing usage.
  • PATCH (1) — incremented for backward-compatible bug fixes. No new functionality, no breaking changes, just a fix.

The rule of thumb: if existing code that uses the package could break after upgrading, it’s a major bump. If it definitely won’t break but new capability was added, it’s minor. If it’s purely a fix with no interface change, it’s patch.

Pre-release and build metadata

SemVer also defines optional suffixes for versions that aren’t yet stable releases:

  • Pre-release: 2.4.1-beta.1, 2.4.1-rc.2 — signals the version is not yet stable and shouldn’t be depended on for production use without care. Pre-release versions have lower precedence than the corresponding release version.
  • Build metadata: 2.4.1+20260712 — additional information that doesn’t affect version precedence at all, often used to tag a specific build from CI.

Version ranges in package managers

Most package managers let you specify a range of acceptable versions rather than pinning an exact one, using SemVer’s structure to express intent:

Range syntaxMeaning
2.4.1Exactly this version
^2.4.1Compatible with 2.4.1 — allows minor and patch updates, blocks major
~2.4.1Approximately 2.4.1 — allows patch updates only
>=2.4.1 <3.0.0Explicit range, equivalent to ^2.4.1

The caret (^) range is the most common default, and it directly encodes SemVer’s promise: minor and patch bumps are supposed to be safe, so package managers install the latest matching minor/patch version automatically, while major version bumps require explicit action from the consumer. This is what makes npm install and similar commands able to resolve a dependency tree automatically most of the time — the ranges assume every package involved is actually following SemVer’s compatibility promise.

Why the convention breaks down in practice

SemVer is a promise, not something enforced by tooling — nothing stops a maintainer from shipping a breaking change in a minor or patch release, whether by accident or because they judge the change to be minor enough not to warrant a major bump. This is a genuinely common source of “why did my build break after a routine update” incidents. A few practical implications:

  • Lockfiles exist for a reason. A lockfile pins exact resolved versions across a dependency tree, so builds are reproducible even though your package.json might specify a range. Without one, two installs on different days can silently resolve to different versions.
  • Read changelogs before major bumps, always. SemVer guarantees a major bump might break something — it’s your signal to actually check, not a guarantee that reading is unnecessary.
  • “Technically a bug fix” is a judgment call. Removing an undocumented behavior that some users were relying on is arguably a patch (it wasn’t part of the documented contract) or arguably a major bump (it broke real users) — reasonable maintainers disagree, which is why version numbers alone are a useful heuristic, not a substitute for testing.

SemVer beyond package managers

Although SemVer originated in and is most closely associated with software package ecosystems like npm, the same three-part logic — breaking, additive, fix-only — is a useful mental model for API versioning, internal library releases, and even how you communicate changes in a CI/CD pipeline. The vocabulary of “major,” “minor,” and “patch” gives teams a shared, low-friction way to signal risk without writing a paragraph of explanation for every release.

Version control systems like Git don’t enforce SemVer at all — tags are just strings — but it’s common practice to tag releases with a SemVer-formatted version (v2.4.1) so tooling that reads Git tags can reason about release history consistently.

The takeaway

Semantic versioning turns a version number into a compatibility signal: major for breaking changes, minor for backward-compatible additions, patch for backward-compatible fixes. It’s the convention that lets automated dependency resolution work at all — package managers can safely auto-update within a range because SemVer promises minor and patch bumps won’t break anything. That promise is only as good as the maintainer’s discipline in following it, so pin dependencies with a lockfile and actually read release notes before taking a major version bump.

The Lycoris Team The Lycoris Team · · 4 min read

What Is a Git Worktree? Multiple Branches, One Repo

A git worktree lets you check out several branches at once in separate folders, sharing one .git history without cloning the repo again.

#Git #Developer Tools #Version Control
The Lycoris Team The Lycoris Team · · 3 min read

What Is Git? Version Control, Explained for Beginners

Git is a distributed version control system that tracks changes to code and enables collaboration. Learn the core concepts and everyday workflow.

#Git #Developer Tools #Version Control
Chisato Chisato · · 4 min read

What Is Prompt Chaining? Multi-Step LLM Pipelines

Prompt chaining splits a task into a sequence of smaller LLM calls, each one feeding the next, instead of asking one giant prompt to do everything.

#AI #LLMs #Developer Tools