Free JavaScript reference · Python timeline

JavaScript ES2026: More expressive collections, bytes, and numeric checks

Async collection, Map upserts, byte codecs, precise summation, JSON source access, error checks, and iterator sequencing join the standard.

Edition 17 · Published · Editorial review October 26, 2026

Standardized in ES2026 · Built-in async API

Array.fromAsync() collects asynchronous values

Array.fromAsync constructs an array from asynchronous or synchronous iterable input, awaiting the produced values. Its optional mapping callback can also be asynchronous.

Collection happens sequentially rather than starting arbitrary work concurrently like a prebuilt list of promises passed to Promise.all. Choose according to ordering, resource limits, and how the input produces values.

The example uses two already available promises and an async mapper. The final promise is retained so a caller can await completion and handle any collection or mapping failure.

Worked example

Uses ES2026 features · Script

const finished = Array.fromAsync([Promise.resolve(2), Promise.resolve(3)], async n => n * 2)
  .then(values => console.log(JSON.stringify(values)));

Expected output

[4,6]

Example checked with Chromium 151.0.7922.34, Node.js 24.19.0.

Common mistake

This API does not promise parallel mapping. A rejected value or failed mapper rejects the collection promise.

Try it yourself

Use an async generator as the source and explain when each value is requested.

Read more: ES2026 specification · MDN explanation and compatibility

Standardized in ES2026 · Built-in method

Map getOrInsert and getOrInsertComputed

getOrInsert returns an existing Map value, or inserts a supplied default if the key is missing. getOrInsertComputed calls a factory only when a default actually needs to be created.

Presence is tested separately from the stored value, so an existing undefined is still an existing entry. The computed form is useful for lazily creating a bucket array without allocating a new one for every repeated key.

The example groups one record ID and confirms that a second lookup reuses the first array. It also verifies that an existing undefined is not replaced.

Worked example

Uses ES2026 features · Script

const groups = new Map();
const bucket = groups.getOrInsertComputed("book", () => []);
bucket.push(7);
console.log(groups.getOrInsert("book", []).length);
groups.set("empty", undefined);
console.log(groups.getOrInsert("empty", 9) === undefined);

Expected output

1
true

Example checked with Chromium 151.0.7922.34.

Required API unavailable in the checked Node.js 24.19.0. See compatibility details before running.

Common mistake

An eager default expression is evaluated before getOrInsert is called. Use the computed form when the construction should happen only for an absent key.

Try it yourself

Count factory calls while looking up the same key twice with getOrInsertComputed.

Read more: ES2026 specification · MDN explanation and compatibility

Standardized in ES2026 · Built-in method

Uint8Array Base64 and hex codecs

Byte-oriented Base64 and hexadecimal helpers convert directly between text encodings and Uint8Array values. They avoid treating an encoded byte sequence as though it were already decoded human-readable text.

Base64 is an encoding, not encryption. These helpers also do not decide which character encoding a byte sequence uses. To obtain text, apply an appropriate decoder after the byte conversion.

The example decodes a two-byte ASCII sequence, prints the numeric bytes, and converts them to both hexadecimal and Base64. For malformed input, handle the API's validation errors deliberately.

Worked example

Uses ES2026 features · Script

const bytes = Uint8Array.fromBase64("SGk=");
console.log(JSON.stringify([...bytes]));
console.log(bytes.toHex());
console.log(bytes.toBase64());

Expected output

[72,105]
4869
SGk=

Example checked with Chromium 151.0.7922.34.

Required API unavailable in the checked Node.js 24.19.0. See compatibility details before running.

Common mistake

Converting Base64 to bytes does not decode UTF-8 or conceal the data. Do not confuse a byte codec with a text or security boundary.

Try it yourself

Change one byte and predict the new hex pair. What extra step would a UTF-8 message need?

Read more: ES2026 specification · MDN explanation and compatibility

Standardized in ES2026 · Built-in function

Math.sumPrecise() reduces summation loss

Math.sumPrecise sums an iterable of Numbers with a more accurate accumulation strategy than naive left-to-right addition. It is useful when values with very different magnitudes would otherwise lose a small contribution.

The result is still a Number, not arbitrary-precision decimal arithmetic. Input validation, representation error in individual operands, infinities, and financial rounding policies remain separate concerns.

In the example, ordinary addition loses the one between two large opposite values. Precise accumulation preserves that contribution before producing the final Number.

Worked example

Uses ES2026 features · Script

const values = [1e16, 1, -1e16];
console.log(values.reduce((total, n) => total + n, 0));
console.log(Math.sumPrecise(values));

Expected output

0
1

Example checked with Chromium 151.0.7922.34.

Required API unavailable in the checked Node.js 24.19.0. See compatibility details before running.

Common mistake

More accurate summation does not turn Number into a decimal-money type or make an already-rounded input exact.

Try it yourself

Reorder the values and compare naive sums. Why is a more stable accumulation method useful even when each input is a valid Number?

Read more: ES2026 specification · MDN explanation and compatibility

Standardized in ES2026 · Built-in API

JSON revivers can access primitive source text

A JSON.parse reviver receives context.source for a primitive value. This allows the reviver to inspect the original JSON token instead of relying only on an already-converted Number.

That distinction matters for a large integer identifier: conversion to Number can lose precision before the reviver sees the numeric value. Reading the original integer token and converting it to BigInt can preserve the intended integer.

The example knows that the id field contains an integer token. A general parser needs an explicit policy for decimals, exponent notation, strings, and which fields should become BigInts.

Worked example

Uses ES2026 features · Script

const data = JSON.parse('{"id":9007199254740993}', (key, value, context) => {
  return key === "id" ? BigInt(context.source) : value;
});
console.log(String(data.id));

Expected output

9007199254740993

Example checked with Chromium 151.0.7922.34, Node.js 24.19.0.

Common mistake

BigInt cannot parse every valid JSON number spelling, such as arbitrary decimal fractions. Restrict this transformation to a documented field contract.

Try it yourself

Compare BigInt(value) with BigInt(context.source) for the identifier and explain where precision can already be lost.

Read more: ES2026 specification · MDN explanation and compatibility

Standardized in ES2026 · Built-in function

Error.isError() checks error identity

Error.isError identifies genuine Error objects without relying on a particular realm's Error constructor. This is helpful when values cross execution contexts, where instanceof can give a misleading result.

An object that merely has a name and message is not automatically a genuine error object. Conversely, JavaScript can throw any value, so rejecting non-Error values as errors does not prove they were never thrown.

The example contrasts a real error with a lookalike record. Keep a fallback reporting strategy for unknown thrown values at application boundaries.

Worked example

Uses ES2026 features · Script

console.log(Error.isError(new TypeError("bad shape")));
console.log(Error.isError({name: "Error", message: "lookalike"}));

Expected output

true
false

Example checked with Chromium 151.0.7922.34, Node.js 24.19.0.

Common mistake

Error.isError is not a guarantee that every rejection reason or thrown value has an Error shape. Handle unknown values safely.

Try it yourself

Catch a thrown string and compare it with a caught new Error. How should a reporting function format both?

Read more: ES2026 specification · MDN explanation and compatibility

Standardized in ES2026 · Built-in method

Iterator.concat() sequences iterable sources

Iterator.concat combines iterable sources into a lazy sequence, consuming one source before moving to the next. It avoids materializing all source contents into a new array just to traverse them.

It is shallow sequencing, not recursive flattening or concurrent asynchronous merging. If a source is itself a one-shot iterator, consuming it changes what remains available for later use.

The example combines two arrays with an empty source between them. Materializing the result at the end makes the expected order easy to inspect.

Worked example

Uses ES2026 features · Script

const combined = Iterator.concat([1, 2], [], [3]);
console.log(JSON.stringify([...combined]));

Expected output

[1,2,3]

Example checked with Chromium 151.0.7922.34.

Required API unavailable in the checked Node.js 24.19.0. See compatibility details before running.

Common mistake

Concatenating iterable sources does not make them replayable or await promised elements. Async iteration needs its own design.

Try it yourself

Use a generator as one source, then try consuming it again after the combined iterator finishes.

Read more: ES2026 specification · MDN explanation and compatibility

Recap

Async collection, Map upserts, byte codecs, precise summation, JSON source access, error checks, and iterator sequencing join the standard. Check the engines your project supports before adopting new syntax or built-ins.

Read the ES2026 specification →