Engineering note

Four ES2026 features worth using

Practical examples of Map upsert, iterator sequencing, lossless JSON parsing, and Uint8Array base64 APIs

By Santosh Kalidindi2 min read

TC39's finished proposals, external site place these APIs in ES2026. Each one replaces code I have written often enough to recognize on sight.

Map upsert without a manual branch

Map.prototype.getOrInsertComputed returns the existing value or computes, stores, and returns a new one. The callback only runs for a missing key.

const users = new Map();

function getUser(id) {
  return users.getOrInsertComputed(id, (key) => ({
    id: key,
    loadedAt: Date.now(),
  }));
}

This removes the repeated has, get, set sequence without changing Map semantics.

Join iterables lazily

Iterator.concat accepts any mix of iterables and returns one lazy iterator. It does not allocate intermediate arrays.

const deployTargets = Iterator.concat(["api", "worker"], new Set(["cron"]));

console.log([...deployTargets]);
// ["api", "worker", "cron"]

The inputs remain separate until iteration starts, which helps when one of them is a generator or a large collection.

Recover exact numbers from JSON

The JSON.parse reviver now receives the original source text for primitive values. That matters when a JSON integer exceeds JavaScript's safe integer range.

const invoice = JSON.parse(
  '{"cents": 9007199254740993}',
  (key, value, context) => (key === "cents" ? BigInt(context.source) : value),
);

console.log(invoice.cents);
// 9007199254740993n

Without context.source, the number has already lost precision before the reviver sees it.

Encode bytes without browser helpers

Uint8Array can decode and encode base64 directly. The code works on bytes, so it avoids the string conversions required by atob and btoa.

const bytes = Uint8Array.fromBase64("SGVsbG8=");

console.log(bytes);
// Uint8Array(5) [72, 101, 108, 108, 111]

console.log(bytes.toBase64());
// "SGVsbG8="

Ship against your runtime matrix

Language editions describe the standard, not the date every runtime ships it. Check the environments you support before removing a compatibility layer.

APIMain benefitMigration risk
Map.prototype.getOrInsertComputedOne atomic-looking upsertCallback behavior
Iterator.concatLazy sequencingIterator consumption
JSON.parse source contextExact numeric recoveryReviver compatibility
Uint8Array base64 methodsByte-native encodingRuntime availability

Treat support as a release constraint

Feature detection is useful for optional behavior. For core data paths, set a minimum runtime version and test it in CI so deployment cannot quietly select an older engine.