Skip to main content

What is semantic versioning?

3 min read

Older Article

This article was published 9 years ago. Some information may be outdated or no longer applicable.

If you’ve worked with Node.js and npm packages, you’ve probably bumped into the term “semver” or semantic versioning. Let’s break down what it means and how it actually works.

Version management

Managing large software projects and their dependencies can turn into a real headache. Every dependency might version itself differently, and without a standard, things get messy fast. You need consistent rules for numbering versions and knowing when to bump them.

That’s why the semantic versioning standard was born. npm (the package manager for Node.js) follows it.

In systems with many dependencies, releasing new package versions can quickly become a nightmare. If the dependency specifications are too tight, you are in danger of version lock (the inability to upgrade a package without having to release new versions of every dependent package). If dependencies are specified too loosely, you will inevitably be bitten by version promiscuity (assuming compatibility with more future versions than is reasonable). Dependency hell is where you are when version lock and/or version promiscuity prevent you from easily and safely moving your project forward.

Semantic versioning in Node.js (npm)

Semantic versioning splits things into three numbers: major, minor, and patch. A package at version 1.3.5 reads like this: major.minor.patch135

How to interpret version numbers

Bumping the major version signals incompatible changes. Bumping the minor version means new functionality that’s backwards-compatible. Bumping the patch version means backwards-compatible bug fixes.

So if a bug fix lands in our imaginary package, the last number ticks up (it’s a patch release): 1.3.6.

New, non-breaking features bump the middle number (a minor release): 1.4.5.

Changes that break backwards compatibility bump the first number (a major release): 2.3.5.

npm and package version numbers

When you install packages with npm, you can specify version ranges or pin exact numbers:

  • package@2.0.0 - install the package with exact version number 2.0.0
  • package >= 1.2.7 - install package with version 1.2.7 or 1.2.8 or even 2.5.5 but never 1.2.6 or smaller
  • package ~1.2.3 - install patch level changes (1.2.3, 1.2.4 but not 1.3.x, nor 2.x)
  • package ^1.2.3 - install minor updates (1.2.3, 1.2.4, 1.5.6 but not 2.x)

npm tagged versions

Sometimes you’ll see version numbers with the @ symbol: package@latest or package@next.

These are tagged versions. Tags sit alongside semantic versioning as a way to organise packages. The latest tag always points to the current stable version. next typically points to the latest beta.