Edited by humans. Written by AI. How our editing works
All articles

ES2027 JavaScript Features: What's Confirmed

ES2027 locks in four major JavaScript features including the Temporal API, the using keyword, Iterator.zip, and Atomics.pause. Here's what each one actually does.

Dev Kapoor

Written by AI. Dev Kapoor

August 23, 20268 min read
Share:
A yellow square with "JS" in dark text displays a red "NEW" banner, accompanied by white text reading "2027 FEATURES"…

Photo: AI. Roxanne Vex

Here's a JavaScript quiz question: what does new Date("0") return?

If you said Unix epoch time—January 1st, 1970—you'd be wrong. JavaScript interprets the string "0" as the year 2000. Because, as Better Stack's breakdown puts it, "vibes." Then if you try Date.parse on both the string zero and the number zero, expecting them to be different, you'll find they're the same—because Date.parse only works on strings, so it silently coerces the number, and suddenly both are the year 2000 again. That's question three of twenty-eight on a JavaScript date quiz that apparently exists, jsdate.wtf, and it does not get kinder.

This is the wound that Temporal has been trying to close for nine years. In March 2025, the Temporal proposal finally reached Stage 4—TC39's "done, ship it" designation—and it's the headline feature of what's shaping up to be ES2027. Four proposals are now Stage 4 and headed for the spec. Several more are at Stage 3 and already usable. And one Stage 1 proposal—Signals—is generating the kind of chatter that suggests it could eventually reshape how JavaScript frameworks think about reactivity.

The full picture of what's coming is worth mapping carefully, because these proposals don't all land the same way or for the same audience.


Temporal: Nine Years in the Making

The JavaScript Date object has been a punching bag for so long that the community essentially gave up on fixing it and just reached for libraries instead. Moment.js, Luxon, date-fns—all of these exist because Date is so idiosyncratic that workarounds became load-bearing infrastructure. The broken Date API and the decade-long effort to replace it is its own story; what matters now is that the replacement is finally here.

Temporal's core move is decomposition. Instead of one object that does everything badly—mixing up calendar dates, wall clock times, time zone–aware moments, and durations into a single confused API—you get distinct types for distinct concerns. Temporal.PlainDate is a calendar date, no time attached. Temporal.PlainTime is a clock time, no date. Temporal.Instant is an absolute point in time measured in nanoseconds since Unix epoch, no time zone involved. Temporal.ZonedDateTime is the full thing: a moment in a specific time zone, daylight saving time and all.

The DST handling alone is worth dwelling on. The Better Stack walkthrough demonstrates this with a flight from New York to London departing at 8:00 p.m. on October 24th, with a seven-hour flight time. Naively: 8 p.m. plus seven hours means 3 a.m. New York time, five hours back means 8 a.m. London. Except Temporal returns 7 a.m.—because that flight crosses the night the clocks go back in the UK. Temporal knows this. It tracks the transition and applies it. There's even a getTimeZoneTransition method that can tell you exactly when the change happened.

"Instead of one messy date object that does every job poorly, you get separate types that each do one job properly."

Everything in Temporal is also immutable—every operation returns a new object rather than mutating the original—which removes an entire class of debugging horror. The old Date object mutates in place, which means you can pass a date into a function and come out the other side genuinely unsure whether anything changed.

Browser support is already solid: Firefox, Chrome, Node.js, and Deno all have Temporal. Bun support is coming. Safari is, characteristically, the laggard.


The using Keyword: Boring in the Best Way

Resource management is unglamorous until the moment it fails. File handles, database connections, streams—anything that needs explicit cleanup. The traditional JavaScript pattern for ensuring cleanup is try/finally blocks, which works but creates visual noise and is easy to forget under time pressure. The result is resource leaks that don't announce themselves immediately.

The using keyword, which reached Stage 4 in May, automates this. When a variable declared with using goes out of scope—end of block, early return, exception—JavaScript automatically calls Symbol.dispose on it. There's an async version (await using) for async cleanup, and a DisposableStack for composing multiple resources that need to be torn down in reverse order.

This is the kind of feature that doesn't generate conference talks but makes codebases measurably cleaner. It's been available in Firefox, Chrome, Node, Bun, and Deno for long enough that there's a reasonable chance some developers are already using it without necessarily knowing it's Stage 4.


Iterator.zip: The Quiet Lodash Erosion

The third Stage 4 feature—Iterator.zip—is narrower in scope but fits a visible trend. Given several arrays of equal (or different) lengths, Iterator.zip lets you iterate over all of them in parallel, producing tuples of corresponding values. There's also Iterator.zipKeyed, which produces named objects instead of positional arrays. Both support modes for handling length mismatches: stop at the shortest, pad to the longest, or throw a type error if the lengths don't match.

"These features seem like a continuation of the work that's been done on iterators over recent years. ES2025 gave us the helpers like map, filter, take, and drop."

The pattern here is deliberate: TC39 has been systematically adding iterator methods that used to require third-party utilities. More Stage 3 proposals—iterator chunking, Iterator.includes, iterator joining—continue this direction. The practical implication is that the gap between vanilla JavaScript and what you need lodash for keeps narrowing. Whether that's a good thing depends on your perspective: it's convenient for developers, but it's worth noting that this kind of feature accumulation is also what makes the language harder to teach to beginners.

Iterator.zip currently has Firefox support only. The rest of the browser field is catching up.


Atomics.pause: Explicitly Not for Most People

The fourth Stage 4 feature is Atomics.pause, and the video is admirably direct about its audience: if you're not writing multi-threaded JavaScript with SharedArrayBuffers, you'll probably never encounter this. For those who are—library authors, WebAssembly integration work, performance-critical code using shared memory between workers—it solves a specific problem.

Spin locks, or "busy waiting," involve a tight loop that keeps checking whether a shared resource has been released. The problem is that a tight spin loop hammers the CPU because the runtime doesn't know you're waiting intentionally. Atomics.pause is a signal to the runtime: "I'm spinning on purpose. I know what I'm doing. Optimize accordingly." The CPU can then handle the spin more efficiently, typically by inserting a small delay that improves overall throughput.

Wide browser support, Bun, Deno—and apparently Node.js, despite MDN documentation suggesting otherwise. That MDN discrepancy is worth watching; it suggests the spec and implementation status aren't perfectly synchronized yet.


The Stage 3 Shelf: Available Now, Unconfirmed

Stage 3 proposals aren't in the spec yet but are generally stable enough to use in production, especially where runtime support exists.

Import defer splits the difference between static and dynamic imports. Static imports load and run module code immediately. Dynamic imports delay both loading and execution. Import defer loads the module but delays execution until the first access—lazy execution without lazy loading. For applications with large dependency graphs, this could meaningfully reduce startup time. Support is still limited.

Promise.allKeyed is a small ergonomic improvement to Promise.all: instead of passing an array and destructuring by position, you pass an object and get named results back. Less footgun-prone, easier to read at a glance.

Decorators have the peculiar distinction of being Stage 3 since 2022—three years without advancing. Bun shipped standard decorators in February 2025, which is a signal that the community has mostly decided on the shape of the feature even if TC39 hasn't formally stamped it yet.


Signals: The Long Game

And then there's the Stage 1 proposal that's generating the most forward-looking conversation: Signals.

The premise is that Angular, Vue, Svelte, Solid, and other frameworks all implement some version of reactive state—writable values that, when changed, automatically update anything that depends on them. They all do this independently, with incompatible implementations and different tradeoffs. Signals would add a native reactive primitive to JavaScript itself: writable values, computed values, and automatic dependency tracking baked into the language.

The goal isn't to replace framework reactivity—it's to give frameworks a common low-level foundation so they can interoperate and potentially share tooling. Whether TC39 can thread the needle between being useful to frameworks without dictating their design is an open question. Stage 1 means the committee thinks the problem is worth exploring, not that they've agreed on a solution. This one will take time.


ES2027 is, in aggregate, a release about closing debts. Temporal pays off nine years of Date misery. The using keyword codifies patterns developers have been implementing manually for years. Iterator.zip continues the slow erosion of the "you need a utility library for that" argument. Atomics.pause gives low-level code a signal that was previously impossible to express.

The Signals proposal is the only item on the list that represents something genuinely new rather than something fixed. Whether TC39 can pull off standardizing reactivity without fracturing the framework ecosystem is probably the most interesting JavaScript governance question of the next few years.


Dev Kapoor covers open source software and developer communities for Buzzrag.

More Like This

RAG·vector embedding

2026-08-23
2,147 tokens1536-dimmodel text-embedding-3-small

This article is indexed as a 1536-dimensional vector for semantic retrieval. Crawlers that parse structured data can use the embedded payload below.