Guidefor developers4 min read
Which Minecraft version is newer, 26.2 or 1.21.11?
Text comparison says 1.21.11 wins. Release order says 26.2 does. Why every naive version sort broke in 2026, and how to order both eras correctly in your own code.
Why every version sorter broke in 2026
Run this and see what you get:
["26.2", "1.21.11"].sort()
// ["1.21.11", "26.2"]
Wrong. 26.2 shipped in 2026 and 1.21.11 shipped in December 2025, so 26.2 is newer. String comparison put 1 before 2 and produced the opposite answer.
Semantic version parsers do no better, because they are working correctly on the wrong assumption. To a semver parser, 26.2 has a major of 26 and 1.21.11 has a major of 1, so 26.2 is newer. That happens to be right here, but only by accident: the same parser will tell you 1.21.11 is newer than 1.21.9, which is true, and that 1.9 is newer than 1.10, which is not, if it is treating the parts as text.
The underlying problem is that Minecraft version names have never been a sortable key.
They are labels. 1.21.11, 26.2, 26w14a, 1.21.11-pre1, 3D Shareware v1.34 and
b1.7.3 are all real version names, and no single parsing rule orders that set correctly.
Use the manifest order
Mojang publishes a version manifest that lists every version it has ever released, in chronological order, in one array. That order is the answer. It is authoritative, it covers both naming eras, it puts snapshots and pre-releases exactly where they belong, and it needs no parsing at all.
The rule is: read the manifest once, assign each version its index, store the index, and sort on the index forever after. Never parse the name.
That index is what this site calls sortIndex, and it is the only ordering used anywhere
on it. When you see a "previous version" and "next version" link on a version page, it is
following that index.
// Assign once at ingest, then never think about version names again.
const manifest = await fetch("https://launchermeta.mojang.com/mc/game/version_manifest_v2.json")
.then((response) => response.json());
// The manifest is newest first, so reverse it to get an ascending index.
const order = new Map(
manifest.versions.map((version, index) => [version.id, manifest.versions.length - index])
);
order.get("26.2") > order.get("1.21.11"); // true, and it will stay true
Sorting by data version, and where that fails
The data version is a plain integer that Mojang increments on every version, including snapshots. It is exposed in a version's own metadata and inside every world save. If both versions you are comparing have one, comparing data versions is correct and needs no network call at runtime.
Where it fails:
- It does not exist below 1.9. Anything older has no data version at all.
- It is not in the manifest. You have to fetch each version's detail document to read it, which is one request per version.
- April Fools versions have one too, and it is a real number that slots them into the middle of whatever year they were released in. That is correct behaviour, and it is probably not what you want in a release picker.
So: data version is the best runtime comparison key, and manifest order is the best ingest time key. Store both.
Never sort by protocol version
Protocol numbers look like they should work and they do not.
- They repeat. 1.21.7 and 1.21.8 both speak protocol 772, because nothing about the network protocol changed between them.
- Snapshots use a separate space. Snapshot protocol numbers are offset by a very large constant so they cannot be confused with release protocols. Sorting a mixed list by protocol throws every snapshot to one end.
Protocol version answers exactly one question, which is whether two builds can talk to each other. It is on every version page here for that reason and no other.
Handling snapshots, pre-releases and release candidates
Within a single release cycle the order is always:
- snapshots, in week order
- pre-releases, numbered from 1
- release candidates, numbered from 1
- the release
The manifest already has them in this order, so if you are using the manifest index you get
it for free. If you are building a version picker, the useful move is to store the release a
pre-release belongs to alongside its index, so you can group 26.2-pre1 through 26.2-rc1
under 26.2 and collapse them by default.
Showing two eras in one dropdown
Users do not have this problem in their heads. They know 26.2 is current and 1.20.1 is old. Where they get confused is a list that mixes the two without saying which is which.
Two things fix it:
- Group by era, and label the groups. "2026 releases" and "1.x releases" is enough.
- Sort descending and never renumber anything. Show the names Mojang published, in the order Mojang published them.
The version list on this site does exactly that, and the era label on each version page is stored as a field rather than guessed from the name.
Test cases every version sorter should pass
If your implementation gets all of these right, it is correct:
| Comparison | Correct answer | What it catches |
|---|---|---|
26.1 vs 1.21.11 | 26.1 is newer | the era boundary |
1.21.11 vs 1.21.9 | 1.21.11 is newer | numeric, not text, comparison |
1.10 vs 1.9 | 1.10 is newer | the same trap one level up |
26.2 vs 26.2-rc1 | 26.2 is newer | candidates precede releases |
26.2-pre1 vs 26.2-rc1 | rc1 is newer | pre-releases precede candidates |
26w14a vs 26.1 | depends on dates | snapshots interleave |
1.21.7 vs 1.21.8 | 1.21.8 is newer | equal protocols must not tie |
b1.7.3 vs 1.0 | 1.0 is newer | beta predates release |
3D Shareware v1.34 | not in a release list | April Fools versions |
The last row is the one most implementations miss. If your sorter has to decide where
3D Shareware v1.34 goes, it is parsing names, and it will keep failing on inputs nobody
predicted. Read the full version list and you will find a dozen more
names no regular expression is going to survive.