JavaScript’s standard, ECMAScript, gets a new edition every June, and the 2025 and 2026 editions between them delivered the biggest practical upgrade in a decade. Three additions change everyday code: Temporal finally replaces the broken Date object, using handles resource cleanup, and iterators gained the array methods everyone reaches for. This is what each one does and when you can rely on it.
Temporal#
The Date object has been the most complained-about part of the language since 1995: mutable, timezone-confused, and with months numbered from zero. Temporal is its replacement, reached the final stage in March 2026, and is being shipped by the major engines.
// Today's date, no time, no timezone confusion
const today = Temporal.Now.plainDateISO();
// A specific date; months are 1-based
const launch = Temporal.PlainDate.from({ year: 2026, month: 10, day: 7 });
// Arithmetic returns new values - nothing is mutated
const review = launch.add({ weeks: 6 });
const gap = today.until(launch); // a Duration
console.log(gap.days);
// A moment in a real timezone, with DST handled correctly
const meeting = Temporal.ZonedDateTime.from('2026-11-01T09:00[Europe/London]');
const inTokyo = meeting.withTimeZone('Asia/Tokyo');
console.log(inTokyo.toString());
// An exact instant, independent of zones
const now = Temporal.Now.instant();
The key idea is separate types for separate concepts. A PlainDate is a calendar date with no time. A PlainTime is a wall-clock time. An Instant is an exact moment. A ZonedDateTime is an instant plus a timezone, which is what you need to say “9am in London”. Date tried to be all of these at once and was none of them reliably.
Every Temporal object is immutable; methods return new ones. Comparing, formatting and parsing all follow ISO 8601 strictly.
using and await using#
Explicit resource management adds a declaration that guarantees cleanup when a block ends, however it ends:
function readConfig(path) {
using file = openFile(path); // must have a [Symbol.dispose]() method
return parse(file.readAll());
} // file[Symbol.dispose]() runs here, even on throw
async function query(sql) {
await using conn = await pool.connect(); // [Symbol.asyncDispose]()
return conn.run(sql);
}
Anything with a Symbol.dispose method works. Runtimes are adding it to their own resources — file handles, database connections, locks — and you can add it to your own classes:
class Timer {
constructor(label) { this.label = label; this.start = performance.now(); }
[Symbol.dispose]() { console.log(this.label, performance.now() - this.start, 'ms'); }
}
function work() {
using t = new Timer('work');
// ... whatever happens, the timing prints when the function exits
}
This replaces the try/finally pattern for cleanup, and unlike try/finally it cannot be forgotten on one of the exit paths. TypeScript supported it first; it is now native.
Iterator helpers#
Generators and other iterators used to need Array.from before you could map or filter them, which materialised the whole sequence. Iterators now have the methods directly, and they are lazy:
function* naturals() {
let n = 1;
while (true) yield n++;
}
const firstFiveEvenSquares = naturals()
.filter(n => n % 2 === 0)
.map(n => n * n)
.take(5)
.toArray(); // [4, 16, 36, 64, 100]
Nothing infinite is ever built, because each step pulls only what the next one asks for. The set includes map, filter, take, drop, flatMap, reduce, forEach, some, every, find and toArray. Iterator.from wraps any iterable so the methods are available on it.
This matters most for large data: reading lines from a stream, walking a tree, paging an API. You compose the pipeline once and it processes one item at a time.
Smaller additions worth knowing#
- Set methods.
a.union(b),intersection,difference,symmetricDifference,isSubsetOf,isSupersetOf,isDisjointFrom. The hand-written spread-and-filter versions can go. - Promise.try. Runs a function that may throw synchronously or return a promise, and gives you a promise either way.
- RegExp.escape. Escapes a string for safe use inside a regular expression, a utility every project had rewritten.
- Error.isError. A reliable check that survives cross-realm objects, unlike
instanceof Error. - Math.sumPrecise. Sums an iterable of numbers without the floating-point drift of a reduce loop.
- Uint8Array to and from base64 and hex.
bytes.toBase64(),Uint8Array.fromBase64(str), and hex equivalents, replacingbtoagymnastics. - Array.fromAsync. Collects an async iterable into an array.
- Import attributes.
import data from './data.json' with { type: 'json' }is the standard form. - Float16Array and Math.f16round. Half-precision floats, mostly for graphics and machine-learning interop.
const admins = new Set(['ann', 'bo']);
const online = new Set(['bo', 'cy']);
admins.intersection(online); // Set {'bo'}
const safe = new RegExp(RegExp.escape(userInput));
const bytes = new TextEncoder().encode('hi');
bytes.toBase64(); // "aGk="
Where these run today#
| Feature | Status | If you need it everywhere |
|---|---|---|
| Temporal | Shipping in current engines; older browsers lack it | Polyfill, or ship for modern targets only |
| using | Current browsers and Node; transpilers support it | TypeScript or Babel emits a fallback |
| Iterator helpers | All current engines | Small polyfill for old browsers |
| Set methods, Promise.try, RegExp.escape | All current engines | Tiny polyfills |
Check a compatibility table for the exact browser versions your users have; the picture changes every few months. For anything transpiled, TypeScript with a recent target and lib setting handles most of the list.
Questions people ask#
Do I need to wait for a “JavaScript 2026” release?
No. Features ship in engines as they reach the final stage, independently of the yearly edition label. Check support per feature, not per year.
Is Date deprecated?
No, and it never will be removed. But new code should not use it; Temporal exists precisely because Date cannot be fixed in place.
Does using work with async cleanup?
Yes: await using calls Symbol.asyncDispose and awaits it, so a database connection can flush before closing.
What about pipeline operators, signals, records and tuples?
All still proposals at earlier stages. Signals is being prototyped by frameworks; records and tuples were withdrawn in their original form. None are usable natively yet.
Where to go next#
- TypeScript 7 — the other big 2026 change for JavaScript developers.
- ES6 and beyond — the earlier modern features.
- Generators and iterators — what iterator helpers build on.