DEV Community

Cover image for TypeScript never ships x.y.0: classifying releases the way projects actually version
robzepdev
robzepdev

Posted on

TypeScript never ships x.y.0: classifying releases the way projects actually version

I'm building a tracker that tells developers which releases of their stack actually matter.
The first problem wasn't AI or scraping. It was a deceptively simple question:

Given a version string, how important is this release?

Why "just use SemVer" doesn't work

The naive rule: x.0.0 is a major, x.y.0 is a minor, everything else is a patch.
It holds for many libraries, and breaks for some of the most popular ones.

I ended up with one classification strategy per project, mapping a version
to one of four buckets: Spotlight (you should look), Latest (new stuff),
Digest (patches, batched weekly) and Preview (beta and rc).

1. semver: the default

x.0.0 → Spotlight, x.y.0 → Latest, patches → Digest. Vite fits perfectly:
after 8.0.0 came 16 patches, 8.0.1 through 8.0.16, in under three months.
A good tracker shows you 8.0.0 and quietly folds the rest into a digest.

2. node: even majors become LTS

Node's even majors (20, 22, 24) become Long Term Support; odd ones don't.
So an even x.0.0 goes to Spotlight, while odd majors and x.y.0 go to Latest.
Same version shape, different meaning.

3. typescript: there is no stable x.y.0

TypeScript doesn't follow SemVer: every x.y can contain breaking changes.
And the numbering is unusual:

5.9.0-beta → 5.9.1-rc → 5.9.2   ← first stable 5.9
Enter fullscreen mode Exit fullscreen mode

A rule that looks for x.y.0 would never flag TypeScript 5.9 at all.
So the strategy is: the first stable version of each x.y that the sources observed is Spotlight;
later ones are Digest. The strategy has to look at history, not just the string.

4. zerover: in 0.x the minor breaks

For libraries still in 0.x, 0.y.0 is effectively a major.
So 0.y.0 → Spotlight, other 0.y.z → Digest, and from 1.0.0 on it falls back to semver.

Previews and noise

Every strategy treats pre-releases the same way. Only suffixes that are exactly
beta or rc (optionally numbered, like -rc.1) count as previews.
Canary, nightly, experimental, alpha and hash- or date-stamped builds
(-rc.0-next-…) aren't tracked at all. They're the bulk of the noise.

Keep it pure, test it on real versions

Each strategy is a pure TypeScript function, with no I/O,
tested against real version histories from npm and GitHub.
Real data catches what toy examples don't: TypeScript's .2, React's
-rc.0-next-<hash> tags, v-prefixed tags.

And when a rule is still wrong for an edge case, a manual override lives
in the database and is never overwritten by the next sync.

What's next

Classification decides what deserves your attention. The next step decides
what to do about it: an AI summary of each important release, with breaking changes,
migration steps and an explicit Action required / Safe to upgrade verdict.
It will be grounded only in the official release notes. If they don't mention
a breaking change, neither will the summary.

You can see the classification at work on an early preview:
Vite's release page: 8.0.0 up front,
the 16 patches folded into a digest. Name and domain are still provisional.

I'm building this in public. If your stack has a versioning scheme that would
break these rules, I'd love to hear about it in the comments.

Top comments (0)