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 |
The three numbers
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.
Version ranges in your dependency file
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.
Numbering your own releases
The same rules make your bot or app pleasant to depend on and easy to reason about later.
- Start at
0.1.0while things are still moving, or1.0.0once you consider it stable enough that breaking changes deserve a warning. - Bump PATCH for a bug fix, MINOR for a new command or feature that doesn't break existing behaviour, MAJOR when you change or remove something people relied on.
- Tag the release in Git so the number points at exact code:
git tag v1.2.0thengit push --tags. Now "which version is deployed?" has an answer you can check. See Git basics. - Keep a short changelog — even a
CHANGELOG.mdwith 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.
The honest caveat
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.
Why it matters on a Falix server
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.