Semver Cheatsheet
Semantic versioning quick reference: version format, range operators, caret vs tilde rules, pre-release tags, and npm version commands.
Version Format: MAJOR.MINOR.PATCH
| Part | When to increment | Example |
|---|---|---|
| MAJOR | Incompatible API change (breaking change). Resets MINOR and PATCH to 0. | 1.4.2 → 2.0.0 |
| MINOR | New functionality added in a backward-compatible way. Resets PATCH to 0. | 1.4.2 → 1.5.0 |
| PATCH | Backward-compatible bug fix only. No new features. | 1.4.2 → 1.4.3 |
MAJOR version 0 (0.y.z) is for initial development — anything may change at any time. 1.0.0 defines the first stable public API.
Range Operators
| Operator | Example | Matches |
|---|---|---|
| Exact | 1.2.3 | Only version 1.2.3 |
| Caret | ^1.2.3 | Compatible with 1.2.3 — locks leftmost non-zero digit |
| Tilde | ~1.2.3 | Patch-level changes only (if minor specified) |
| Greater than | >1.2.3 | Any version strictly greater than 1.2.3 |
| Greater or equal | >=1.2.3 | 1.2.3 and any version above |
| Less than | <2.0.0 | Any version below 2.0.0 |
| Less or equal | <=1.9.9 | 1.9.9 and any version below |
| Wildcard | * or x | Any version |
| Hyphen range | 1.2.3 - 2.0.0 | >=1.2.3 <=2.0.0 (both ends inclusive) |
| OR | ^1.2.3 || ^2.0.0 | Either range — useful for dual support |
Caret (^) Rules
The caret locks the leftmost non-zero version number. This means it behaves differently for 0.x versions:
| Range | Equivalent to | Allows |
|---|---|---|
^1.2.3 | >=1.2.3 <2.0.0 | Minor and patch updates |
^1.2 | >=1.2.0 <2.0.0 | Minor and patch updates |
^0.2.3 | >=0.2.3 <0.3.0 | Patch updates only (MINOR is leftmost non-zero) |
^0.0.3 | >=0.0.3 <0.0.4 | Exact version only (PATCH is leftmost non-zero) |
Tilde (~) Rules
The tilde allows patch-level changes when a minor version is specified, or minor-level changes when only a major is given:
| Range | Equivalent to | Allows |
|---|---|---|
~1.2.3 | >=1.2.3 <1.3.0 | Patch updates within 1.2.x only |
~1.2 | >=1.2.0 <1.3.0 | Patch updates within 1.2.x only |
~1 | >=1.0.0 <2.0.0 | Minor and patch updates within major 1 |
Pre-release Tags
Append a hyphen and identifier after the patch number. Pre-releases have lower precedence than the associated normal version:
| Tag | Example | Meaning |
|---|---|---|
| alpha | 1.0.0-alpha.1 | Early unstable build; may change drastically |
| beta | 1.0.0-beta.3 | Feature-complete but not yet stable; bugs expected |
| rc | 1.0.0-rc.2 | Release candidate; only critical bug fixes expected |
Precedence order (ascending): 1.0.0-alpha.1 < 1.0.0-alpha.2 < 1.0.0-beta.1 < 1.0.0-rc.1 < 1.0.0
npm version Commands
# Bump version and create a git tag automatically
npm version patch # 1.2.3 → 1.2.4
npm version minor # 1.2.3 → 1.3.0
npm version major # 1.2.3 → 2.0.0
npm version prerelease # 1.2.3 → 1.2.4-0 (or increments pre-release number)
npm version prepatch # 1.2.3 → 1.2.4-0
npm version preminor # 1.2.3 → 1.3.0-0
npm version premajor # 1.2.3 → 2.0.0-0
npm version 2.1.0 # Set exact version
npm version --no-git-tag-version patch # Bump without git tag Common Mistakes
- Using ^ with 0.x packages:
^0.2.3only allows patch changes (<0.3.0), not minor changes. Many devs assume it behaves like^1.x. - Forgetting ^ locks the major:
^1.2.3will never install 2.0.0 automatically, even if 2.0.0 is the latest. - Mixing ~ and ^ without understanding: Use ~ when you only want bug fixes and are worried about minor breaking changes. Use ^ (npm default) when you trust the package maintainer's semver.
- Not committing package-lock.json: The lock file pins exact versions. Without it,
npm installmay resolve different patch versions across environments.
Understand and compare semver ranges interactively with the Semver Explainer tool.
Frequently Asked Questions
What does ^ mean in package.json?
The caret (^) is npm's default version range prefix meaning "compatible with". For ^1.2.3 it means >=1.2.3 <2.0.0 — npm can install newer minor and patch releases but will never cross the major version boundary. It locks the leftmost non-zero digit.
What is the difference between ~ and ^ in semver?
Tilde (~) is more restrictive: ~1.2.3 means >=1.2.3 <1.3.0 (patch changes only). Caret (^) is more permissive: ^1.2.3 means >=1.2.3 <2.0.0 (minor and patch changes). Use ~ when you're conservative about updates (e.g., pinning to a specific API shape); use ^ when you trust the library's semver and want security and bug fixes automatically.
Does ^1.2.3 allow 2.0.0?
No. ^1.2.3 is equivalent to >=1.2.3 <2.0.0, so 2.0.0 is explicitly excluded. Major version bumps indicate breaking changes, so semver protects you by never automatically upgrading across them. To explicitly allow 2.0.0 you'd need to update your package.json to ^2.0.0 or >=1.2.3.