Only show guides for your app
What MAJOR.MINOR.PATCH actually promises — how to read a dependency's version before you update it, how version ranges like ^ and ~ behave, and how to number your own bot or app releases.
A version number is a promise. When a library jumps from 4.18.2 to 4.18.3 it's promising the change is safe; when it jumps to 5.0.0 it's warning you it isn't. Learning to read those numbers — and to write honest ones for your own releases — turns updating dependencies from a gamble into a decision. This is semantic versioning (semver), and it's the convention almost the whole ecosystem follows.
| At a glance | |
|---|---|
| You need | Nothing but a project with dependencies, or one you release yourself |
| Plan | Any |
| Time | Ten minutes to learn, used forever |
A semver version is MAJOR.MINOR.PATCH — for example 2.4.1.
| Part | Bumps when… | What it promises you |
|---|---|---|
MAJOR (2.x.x) |
A change breaks existing usage | Expect to change your code; read the changelog |
MINOR (x.4.x) |
New features are added, backward-compatible | Safe to take; new things you can ignore |
PATCH (x.x.1) |
A bug fix, nothing else changes | Safe to take; just do it |
Read updates through that lens. On the Packages page, the patch / minor / major update badge is literally telling you which of these a version jump is — and therefore how much care it deserves. A patch bump you apply without thinking; a major bump you read about first. See Dependency hygiene.
🎯 Good to know: The map is simple — patch = safe, minor = probably safe, major = read first. That single sentence handles most of the updating decisions you'll ever make.
Your package.json (and its cousins) rarely pin one exact version. They pin a range, and the symbol in front decides how far an install is allowed to move:
| You write | Install may go up to | Meaning |
|---|---|---|
^4.18.0 (caret) |
<5.0.0 |
Newest minor and patch — the common default |
~4.18.0 (tilde) |
<4.19.0 |
Newest patch only — more conservative |
4.18.0 (exact) |
4.18.0 |
Exactly this, nothing else |
* or latest |
anything | Whatever's newest — avoid; it invites surprise breakage |
This is why Installed can differ from Requested on the Packages page: your range said "any 4.x," so the install picked the newest 4.x. To make every install identical regardless of ranges, commit your lockfile — it records the exact resolved version. (More in Dependency hygiene.)
⚠️ Heads up: Versions below
1.0.0play by looser rules. A0.x.yproject is saying "still stabilising" — a bump from0.3.0to0.4.0is allowed to break things even though it's only a minor. Treat every0.xupdate like a major one and read the notes.
The same rules make your bot or app pleasant to depend on and easy to reason about later.
0.1.0 while things are still moving, or 1.0.0 once you consider it stable enough that breaking changes deserve a warning.git tag v1.2.0 then git push --tags. Now "which version is deployed?" has an answer you can check. See Git basics.CHANGELOG.md with a line per release. Future-you updating a dependency wants exactly what you'd want from theirs.Pre-release and build labels exist for when you need them: 1.0.0-beta.1 marks a version as not-yet-final (it sorts before 1.0.0), and a +build.5 suffix carries build metadata. You rarely need either for a small project — reach for them only when you're publishing betas.
Semver is a convention, not a law. Some projects use calendar versions (2024.7.0), and a few break things in a "minor" release despite the promise. So the version number tells you what to expect, and the release notes tell you what actually happened. For anything bigger than a patch, a thirty-second glance at the changelog is never wasted — the full spec lives at semver.org if you want the exact wording.
Dependencies auto-install on every start here, so a loose range (^ or worse, *) means a routine restart can quietly pull in a newer version you never chose. That's not a reason to fear updates — it's a reason to pin with a lockfile and update on purpose on the Packages page, rather than letting the next boot surprise you. Deliberate beats accidental, every time.