You already know what Temporal is. Immutable, timezone-aware, fixes the thirty years of pain that came from porting java.util.Date into JavaScript in 1995. That part of the internet is covered.
What's less covered: whether you should actually flip the switch on your own codebase this quarter, or wait. Here's where things stand and how to decide.
Where support actually is right now
Firefox shipped it by default in Firefox 139, back in May 2025. Chrome caught up in Chrome 144, January 2026. Node.js added it unflagged in Node 26, released in May 2026. Safari is the holdout, still sitting in Technology Preview behind a flag, no ship date announced.
That gap matters more than the version numbers suggest. Because every iOS browser runs on WebKit under the hood, no Safari support means no iPhone or iPad support either, regardless of which browser your users think they're using. Overall coverage on caniuse sits around 69%, and nearly the entire missing third is Safari.
The actual decision, not the marketing version
Skip the "just adopt it, it's the future" advice. Three questions determine whether this quarter is the right time.
Where does your code run. Backend-only or CLI tooling on Node 26+ can go native today, no polyfill, no bundle cost. Anything touching a browser still needs to account for Safari, full stop.
How much Safari traffic do you actually have. Check your analytics before deciding anything. A dashboard used internally on company Chrome installs is a different call than a consumer app with meaningful iOS share.
What's your bundle budget. The two production polyfills aren't free. @js-temporal/polyfill, maintained by the proposal's own champions, runs about 56KB minified and gzipped. temporal-polyfill from the FullCalendar team trims that to roughly 20KB by skipping BigInt internally. Neither is nothing if you're chasing Core Web Vitals.
The pattern that actually ships safely
Feature-detect and load conditionally, so Chrome, Firefox, and Node users never download code they don't need. Check if typeof Temporal is undefined, and if so, dynamically import temporal-polyfill/global before using it. From there, Temporal.PlainDate.from("2026-08-01") gives you a plain date, and calling .add({ months: 1 }) on it returns a brand new object a month later, the original stays untouched.
Only Safari users pay the download. Everyone else runs native code with zero overhead.
The gotcha nobody's tutorial mentions
Every migration guide shows clean examples starting from a fresh Temporal.PlainDate.from(...). Nobody talks about what's already sitting in your database.
If you're storing ISO strings or epoch milliseconds today (and you almost certainly are), the real work isn't learning the new API, it's deciding which Temporal type each existing field actually represents. A created_at timestamp is an Instant. A user's stored birthday is a PlainDate, no timezone attached. A recurring meeting time is a PlainTime combined with a timezone identifier, not a ZonedDateTime baked at creation, or your 9am meeting turns into 8am after the next DST shift.
Get that mapping wrong once at the schema level and you'll be debugging timezone drift for months. Get it right, and this is the last time you'll ever have to think about it.
Quick recommendation
New Node-only backend service: go native now, no polyfill needed.
New frontend project with low Safari traffic: ship the lightweight polyfill, drop it once Safari lands.
Existing frontend with a heavy iOS user base: wait, or pilot the migration on one non-critical feature first.
Anything doing date math inside a hot render loop: worth benchmarking either way, native engines have already closed most of the performance gap against userland libraries.
If you've already migrated a production app, I'd genuinely like to hear what broke. The database mapping problem above is the part I haven't seen written up anywhere yet.
Top comments (0)