Stack Signal WEDNESDAY, SEPTEMBER 16, 2026 · 47 articles · RSS
TC
TechCircuit.
Technical news & guides across AI, programming and the open-source world

Programming & Web DevSep 16, 2026533 words

What's Actually New in ECMAScript 2026

ECMAScript 2026 — the 17th edition of the JavaScript standard — was ratified by Ecma International on June 30, 2026. It has no headliner. There is no Temporal, no decorators, no pattern matching. What shipped instead is exactly seven small additions, and every one of them exists to delete a specific piece of boilerplate or kill a specific footgun.

That is worth celebrating. The most useful language features are rarely the flashiest. Here is what the seven look like in real code.

Math.sumPrecise(): sums that don't lie

0.1 + augment 0.2 is the classic floating-point headache, but the quieter version bites in real code:

const prices = [1e17, 1, -1e17];
prices.reduce((a, b) => a + b); // 0 — the 1 is lost
Math.sumPrecise(prices);        // 1

A plain reduce can silently drop small values when they cancel against huge ones. Math.sumPrecise uses a compensated summation algorithm so intermediate precision never gets thrown away.

getOrInsert(): stop the has-then-set dance

Building a Map incrementally always meant the same two lines:

if (!groups.has(key)) groups.set(key, []);
const list = groups.get(key);

Map.prototype.getOrInsert collapses both into one call. When the default is expensive to build, getOrInsertComputed defers it until the key is actually missing — the same idea as Python's setdefault or Java's computeIfAbsent, and it works on WeakMap too. Grouping data is a constant need, whether you're tallying leaderboard scores or clustering API records, so this single method removes a lot of repetition.

Array.fromAsync(): gather async streams in one line

Collecting a paginated API used to mean a for await loop pushing into an array. Now it is a single expression:

const allItems = await Array.fromAsync(fetchPages("/api/items"));

Native base64 and hex on Uint8Array

Browsers finally get a byte-array conversion that doesn't run through btoa and String.fromCharCode. Uint8Array.fromBase64, fromHex, toBase64, and toHex handle binary data directly, and they accept options for the base64url alphabet when you need it.

JSON that round-trips BigInt

JSON.parse("999999999999999999") silently loses precision — the number just isn't representable. ES2026 hands the reviver a third argument with the raw source text, so you can reconstruct the value exactly:

JSON.parse("999999999999999999", (key, value, { source }) =>
  typeof value === "number" ? BigInt(source) : value
);

Paired with JSON.rawJSON() on the stringify side, BigInts can finally survive a full JSON round-trip losslessly.

Iterator.concat(): sequence lazy iterables

Chaining two iterators used to mean writing a generator with yield*. Now:

const records = Iterator.concat(cached, database, generated);

It is lazy — nothing is materialized into an intermediate array — which matters when you're streaming large sequences.

Error.isError(): realm-proof checks

instanceof Error lies across realms. An error thrown inside an iframe or a worker has a different Error constructor, so the check returns false on a perfectly real error. Error.isError is realm-agnostic:

Error.isError(new TypeError("bad")); // true
Error.isError({ message: "fake" });  // false

What's next

Temporal — the long-awaited replacement for Date — and Explicit Resource Management (using / await using) are the obvious follow-ups, but both are slated for ES2027, not this release. For now, ECMAScript 2026 is a reminder that the best updates often make boring code slightly shorter. That is exactly the kind of progress you feel every day.