The Temporal API is JavaScript's built-in replacement for the Date object, and as of 2026 you can actually use it in production browsers. It reached TC39 Stage 4 on March 11, 2026, which makes it part of the official ES2026 specification. Chrome 144 shipped it in January 2026, Firefox has it from version 139, and Edge picked it up in 144. Safari has most of it in Technical Preview, some pieces still behind a flag.

I have been waiting nine years for this. If you have ever tried to add one month to a date in plain JavaScript and gotten March 31 turning into March 3, you know exactly why.

Why Date needed replacing

The original Date object was ported from Java in 1995 and has been frozen in its mistakes ever since. It is mutable, so passing a date into a function can silently change it for the caller. It has no real time zone support beyond the user's local zone and UTC. Month numbers start at zero while day numbers start at one. Parsing a date string produces different results in different engines.

Every JavaScript project I have worked on eventually pulled in Moment, then date-fns, then Day.js, purely to work around these problems. That is a lot of kilobytes to fix something the language should have handled.

Step 1: Check what you actually have

Temporal lives on a global namespace object. Before you build anything on it, confirm the runtime supports it:

For production code today, I would still load a polyfill as a fallback rather than assume every visitor is on a current browser. Safari users in particular are not there yet.

Step 2: Learn the four types you will actually use

Temporal splits the vague concept of "a date" into separate types, and picking the right one is most of the learning curve. There are more than four in total, but these cover the vast majority of real work:

The distinction that took me longest to internalize: a meeting at 9am next Tuesday is a PlainDateTime until you decide which zone it happens in. A server log entry is an Instant. Conflating those two is the source of most date bugs I have ever debugged.

Step 3: Do arithmetic without losing your mind

Temporal objects are immutable. Every operation returns a new object, so nothing you pass into a function can be mutated behind your back. Arithmetic uses add and subtract with a plain object:

Compare that to the old approach, where adding a month meant reading the current month, incrementing it, then manually checking whether the day overflowed. Temporal clamps January 31 plus one month to February 28 instead of silently rolling into March. That single behavior fixes a category of billing bugs I have seen in production more than once.

Step 4: Handle time zones properly

This is where Temporal earns its size. Time zone conversion used to require a library and a lot of trust:

Nepal is on a 45 minute offset, which historically broke a genuinely surprising number of date libraries. Temporal handles it because it uses the IANA time zone database directly rather than reimplementing offset math.

Step 5: Migrate incrementally

You do not have to rewrite everything. Temporal interoperates with the old API through conversion methods, so you can adopt it at the edges of a codebase and leave the middle alone:

The pattern I have settled on: convert to Temporal as early as possible when data enters the app, do all reasoning in Temporal, and convert back to Date only at the boundary where some library demands it.

What it costs you

Temporal is big. Roughly 4,500 tests were added to the Test262 conformance suite for this feature alone, which gives you a sense of the surface area. The polyfill is not small, so if you are supporting older browsers you are trading one library's bytes for another's. The upside is that once native support is universal, that cost drops to zero, which is not something date-fns will ever do for you.

Performance has stopped being an argument against it. Now that Chrome and Firefox both ship native implementations, the gap against userland libraries has largely closed, which matters for anything doing hundreds or thousands of date calculations in a render loop. If your app is doing that much date math, though, that might be worth looking at separately alongside your other Core Web Vitals work.

Would I use it today?

In a new project targeting evergreen browsers, yes, with a polyfill fallback. In an existing app with a working date-fns setup and no date bugs, I would leave it alone for now and revisit once Safari ships stable support. Rewriting working date code for its own sake is how you introduce the exact bugs Temporal was designed to prevent.

What I am genuinely glad about is that the arguing is over. For nine years the answer to "how do I handle dates in JavaScript" was "pick a library and hope." Now there is a real answer in the language.

Reference: MDN Temporal documentation and the TC39 Temporal proposal docs.

Previous Post Next Post