Skip to main content

What is Semantic Versioning (semver)

What is "semantic versioning" (often called "semver")? (Specifically, semver v2.0.0.) It's detailed in full on its website (https://semver.org) but here's a quick summary and some notes on how it is used in npm.

Version Format

The version format is: MAJOR.MINOR.PATCH, with each part being a number.

  • MAJOR: incremented for a change that is not backwards compatible.
  • MINOR: incremented for new features that are backwards compatible.
  • PATCH: incremented for bug fixes that are backwards compatible.

Examples:

  • A "major" change: 6.0.0 changes the API that was in version 5. Changes could be only in a single part of the API or across the entire API. Users will need to update their code to use the update if they're using the changed API.
  • A "minor" change: 3.2.0 adds a new feature that wasn't in version 3.1. Users will not need to change any of their code to use this update.
  • A "patch" change: 5.3.6 fixes bugs in version 5.3.5 without adding features or changing public interfaces. Users will not need to update their code to use this update.

Major Version 0

Major version 0 (0.0.0, 0.12.3, 0.x.x, etc.) is special cased. They are considered unstable. Even minor and patch updates within major version 0 are considered breaking changes. Major version 0 is intended for initial development before an official public release.

Pre-releases

Pre-releases can be released under the format MAJOR.MINOR.PATCH-PRERELEASE where PRERELEASE can be versioned numbers or letters. Typical values for PRERELEASE are "alpha", "beta", "rc" (for release candidate"), and many more. Prereleases are meant for testing the public release in such a way that doesn't disrupt any users on the public versions.

Examples:

  • 1.0.0-alpha
  • 1.2.3-alpha.1
  • 5.6.2-beta

Npm

Npm's installer behaves as if all npm packages follow semver. However, partial dependency versions may be listed. Meaning, you may leave out PATCH or even MINOR version parts. (Like "express": "4.21" or "express": "4").

Npm also gives you full control over how flexible you want to be regarding which versions to install, explained in brief below.

Npm's full documentation on its behavior is at https://www.npmjs.com/package/semver.

Exact Version

If you have an exact dependency version listed in your package.json, npm will always install that exact version. This is unnecessary for dependencies that correctly follow semver. It also creates headaches for downstream dependencies when upstream dependencies publish bug fixes (though you can often workaround that issues with the package.json field overrides).

Example: "express": "4.21.0"

~ Tilde Version Prefix

The tilde, ~, prefix allows all versions that only change the last specified version number. This prefix is less common but is particularly useful for limiting a specific troublesome dependency to just patch updates.

Examples:

  • "express": "~4.21.0": will allow all patch versions of 4.21.
  • "express": "~4.21": will allow all minor versions of 4.

^ Caret Version Prefix

The caret, ^, prefix allows all versions that do not change the first specified version number. This is the default and most common prefix. When dependencies properly follow semver, you can safely install any version matched with the caret prefix because it will be backwards compatible.

Examples:

  • "express": "^4.21.0": will allow all minor and patch versions of 4.
  • "express": "^4.21": will also allow all minor and patch versions of 4

Major version 0

As aforementioned, major version 0 is a special case in semver. Because of that, npm handles its ranges differently for each prefix. Read npm's full docs for more details.

Prerelease versioning

Npm will not install prerelease versions matching your specified version constraints unless you explicitly use the prerelease version itself. You can allow prerelease matches by providing the --include-prerelease npm flag.

Other Npm Version Constraints

There are other version constraints you can use as well:

  • *: any version (don't use this for public dependencies)
  • -: specify a range of versions with a hyphen, like 1.2 - 3.5
  • >=, >, <=, <: these are all supported ranges, like >=2.1.5
  • x: the letter x may be substituted for any part of the version numbers and means "any value", like 2.3.x
  • ||: "or" multiple versions together with ||