JavaScript Temporal API Reaches Stage 4 — Firefox Ships It by Default

After nine years of design work, the TC39 Temporal proposal reached Stage 4 in early 2025. Firefox 139 became the first major browser to ship Temporal enabled by default in May 2025, with Chrome and Safari implementations following.

Nine Years in the Making

The JavaScript Date object has been broken since 1995 -- months are zero-indexed, parsing is implementation-defined, and there is no calendar or timezone concept. The Temporal proposal started as a champion-less idea on the TC39 issue tracker around 2016, picked up champions in 2018, and reached Stage 3 (implementation-ready) in March 2021. Reaching Stage 4 requires two independent browser implementations passing the full test262 conformance suite. That milestone was cleared in early 2025 after Google, Mozilla, and Apple all landed complete implementations.

Firefox 139: First to Ship by Default

Firefox 139, released in May 2025, was the first browser to enable Temporal for all users without any flag. The Mozilla team had been running the implementation behind a flag since 2023 and spent 2024 fixing edge cases in calendar arithmetic, disambiguation rules, and IANA timezone database integration. The release made every Firefox user a Temporal user overnight -- an estimated 180 million people.

What Temporal Actually Provides

Temporal introduces distinct immutable types: Temporal.Instant (a UTC nanosecond count replacing Date), Temporal.ZonedDateTime (instant + IANA timezone + calendar), Temporal.PlainDate, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.Duration. Months are 1-indexed. Arithmetic is explicit. DST disambiguation is required -- you must specify "earlier", "later", "compatible", or "reject" when a wall-clock time does not exist or is ambiguous. The BigInt-based nanosecond epoch in Temporal.Instant side-steps the 2038 and 275760 overflow issues of the 32- and 64-bit Date objects.

Migrating From Date

Temporal.Instant.fromEpochMilliseconds(date.getTime()) and new Date(instant.epochMilliseconds) bridge the old and new APIs. Libraries like Luxon and date-fns are adding Temporal-backed internals while keeping their existing method surfaces for backward compatibility. The polyfill (@js-temporal/polyfill on npm) has been production-ready since 2022 and is used in thousands of projects already.

Sources