A lightweight polyfill for Temporal, successor to the JavaScript Date object 🕒
Less than 20 kB, spec compliant
🌳 Need an even smaller footprint? Check out the tree-shakeable API
- Installation
- Package Entrypoints
- CDN Usage
- Global TypeScript Types
- Spec Compliance
- Supported Environments
- Comparison with
@js-temporal/polyfill - Tree-shakeable API
npm install temporal-polyfill
import 'temporal-polyfill/global' // most common entrypointOr learn about CDN usage
The following entrypoints support the iso8601 and gregory calendar systems only:
-
Global polyfill. Uses native if available. 👈 What most people need
import 'temporal-polyfill/global' Temporal.Now.zonedDateTimeISO().toString()
-
Local side-effect-free import (ponyfill). Uses native if available
import { Temporal } from 'temporal-polyfill' Temporal.Now.zonedDateTimeISO().toString()
-
Forced non-native side-effect-free import
import { Temporal } from 'temporal-polyfill/implementation' Temporal.Now.zonedDateTimeISO().toString()
-
Install the global polyfill when you want
import { install } from 'temporal-polyfill/shim' install() // uses native if available Temporal.Now.zonedDateTimeISO().toString()
-
Install the non-native implementation globally based on a custom condition
import { installImplementation } from 'temporal-polyfill/shim' if (!globalThis.Temporal || CUSTOM_CONDITION) { installImplementation() } Temporal.Now.zonedDateTimeISO().toString()
The /full/ entrypoints support an expanded set of calendar systems: buddhist, chinese, coptic, dangi, ethiopic, ethioaa, hebrew, indian, islamic-civil, islamic-tbla, islamic-umalqura, japanese, persian, and roc.
-
Global polyfill. Uses native if available
import 'temporal-polyfill/full/global' Temporal.Now.zonedDateTimeISO().withCalendar('buddhist').toString()
-
Local side-effect-free import (ponyfill). Uses native if available
import { Temporal } from 'temporal-polyfill/full' Temporal.Now.zonedDateTimeISO().withCalendar('buddhist').toString()
-
Forced non-native side-effect-free import
import { Temporal } from 'temporal-polyfill/full/implementation' Temporal.Now.zonedDateTimeISO().withCalendar('buddhist').toString()
-
Install the global polyfill when you want
import { install } from 'temporal-polyfill/full/shim' install() // uses native if available Temporal.Now.zonedDateTimeISO().withCalendar('buddhist').toString()
-
Install the non-native implementation globally based on a custom condition
import { installImplementation } from 'temporal-polyfill/full/shim' if (!globalThis.Temporal || CUSTOM_CONDITION) { installImplementation() } Temporal.Now.zonedDateTimeISO().withCalendar('buddhist').toString()
Globally install the polyfill that supports only the iso8601 and gregory calendar systems. Uses native if available.
<script src='https://cdn.jsdelivr.net/npm/temporal-polyfill@1.0.1/global.min.js'></script>
<script>
console.log(Temporal.Now.zonedDateTimeISO().toString())
</script>Globally install the /full/ polyfill that supports an expanded set of calendar systems: buddhist, chinese, coptic, dangi, ethiopic, ethioaa, hebrew, indian, islamic-civil, islamic-tbla, islamic-umalqura, japanese, persian, and roc.
<script src='https://cdn.jsdelivr.net/npm/temporal-polyfill@1.0.1/full/global.min.js'></script>
<script>
console.log(Temporal.Now.zonedDateTimeISO().withCalendar('buddhist').toString())
</script>If using the temporal-polyfill/global or temporal-polyfill/full/global entrypoints, you must configure types:
In your tsconfig.json:
{
"compilerOptions": {
+ "lib": ["esnext"]
}
}Or with more granularity:
{
"compilerOptions": {
+ "lib": ["esnext.temporal", "esnext.intl", "esnext.date"]
}
}Write an ESM import that loads the types:
import 'temporal-polyfill/global'
+ import 'temporal-polyfill/types/global'
console.log(Temporal.Now.zonedDateTimeISO().toString())All time zones are supported. The following calendar systems are supported: buddhist, chinese, coptic, dangi, ethiopic, ethioaa, hebrew, indian, islamic-civil, islamic-tbla, islamic-umalqura, japanese, persian, and roc.
Compliance with the latest version of the Temporal spec is near-perfect with just 1 intentional deviation.
| Browser | Minimum Release | For chinese, dangi, islamic-umalqura
|
|---|---|---|
| Chrome | 67 (May 2018) | 80 (Feb 2020) |
| Firefox | 68 (Jul 2019) | 76 (May 2020) |
| Safari | 14 (Sep 2020) | 14.1 (Apr 2021) |
| Safari iOS | 14 (Sep 2020) | 14.5 (Apr 2021) |
| Edge | 79 (Jan 2020) | 80 (Feb 2020) |
Node.js is supported down to version 16 (Released Apr 2021, EOL since Sep 2023)
| Package |
temporal-polyfill
|
@js-temporal/polyfill
|
| Repo | fullcalendar/temporal-polyfill | js-temporal/temporal-polyfill |
| Creators | FullCalendar lead dev arshaw | Champions of the Temporal proposal |
| Min+gzip size | 19.6 kB, 23.5 kB (full) | 52.1 kB (+166%, +122%) |
| Spec date | June 2026 | March 2025 |
| BigInt approach | Uses real bigint sparingly |
Internally relies on JSBI |
| Global install | Possible via ESM and CDN | Not currently possible |
For anyone hyper-concerned about bundle size, temporal-polyfill also ships an
alternate function API designed for tree-shaking. Instead of large Temporal.*
classes, every operation is a standalone function that acts on a plain record,
so a bundler keeps only the functions you actually import.
import * as PlainDateFns from 'temporal-polyfill/fns/PlainDate'
const date = PlainDateFns.create(2026, 6, 1)
const later = PlainDateFns.addMonths(date, 2)
PlainDateFns.toString(later) // '2026-08-01'🤝 Building a component library? The function API is built to be a shared, deletable peer dependency for third-party tools like date pickers and schedulers. See For component authors.
Each Temporal type has its own entrypoint under temporal-polyfill/fns/* — for
example temporal-polyfill/fns/PlainDate or temporal-polyfill/fns/ZonedDateTime.
Best of all, this isn't a one-way door. When the time is right — once native
Temporal is available in every environment you target, and you no longer need
the polyfill — temporal-polyfill-codemod
rewrites your function calls back into idiomatic Temporal.* expressions.
So PlainDateFns.addMonths(date, 2) becomes date.add({ months: 2 }),
with no manual find-and-replace.
📖 Read the full Tree-shakeable API docs →
The docs cover the complete catalog of functions, their TypeScript type exports,
the codemod workflow, and how each function maps back to the standard Temporal
API.