Jan 20 2024 ~ 2 min read

SemVer Semantic Versioning in package.json: What Do ^, ~, and * Really Mean?


๐Ÿ“ฆ Understanding Semantic Versioning in package.json

If youโ€™ve worked with npm or any JavaScript project, youโ€™ve seen version numbers like ^1.2.3 or ~4.5.6 in your package.json. Hereโ€™s a quick breakdown of what they mean and why they matter.

๐ŸŽฏ The Format: MAJOR.MINOR.PATCH

Semantic Versioning (SemVer) uses three numbers:

  • MAJOR: Breaking changes
  • MINOR: New features, backward-compatible
  • PATCH: Bug fixes, backward-compatible

Example:
2.3.4 โ†’ MAJOR: 2, MINOR: 3, PATCH: 4

๐Ÿ” Prefixes and What They Do

In package.json, we often prefix versions to allow for updates:

  • ^ (Caret): Updates to the latest minor and patch version.
    Example: ^1.2.3 allows anything from 1.2.3 to <2.0.0.

  • ~ (Tilde): Updates only to the latest patch version.
    Example: ~1.2.3 allows anything from 1.2.3 to <1.3.0.

  • No Prefix: Locks the version.
    Example: 1.2.3 means only use that version.

  • * (Wildcard): Allows any version. Use with caution.

โœ… When to Use What

  • Use ^ for libraries you trust to follow SemVer properly.
  • Use ~ when you want more stability (e.g., for shared tools).
  • Avoid * or unpinned versions in production.
  • Use exact versions when debugging or building reproducible environments.

๐Ÿ”’ Pro Tip: Lock it Down

Even with flexible ranges, always check in a package-lock.json or pnpm-lock.yaml to pin exact resolved versions for your builds.

Want to go deeper? semver.org has the full spec.

Headshot of Alvaro Uribe

Hi, I'm Alvaro. I'm a software engineer from Chile ๐Ÿ‡จ๐Ÿ‡ฑ based in New Zealand ๐Ÿ‡ณ๐Ÿ‡ฟ.