mrkeyoor.com_
Mon 02 Nov 22:45 UTC
npmUtilsupdated 02 Nov 2026

@js-temporal/polyfill review

A birthday needs a calendar date; a payment log needs an exact point in time. @js-temporal/polyfill 0.5.1 gives JavaScript those separate types through the Temporal API. PlainDate represents a calendar date independent of a time zone. Instant represents an exact point in time, while PlainDateTime can hold local date and clock fields before you choose a zone. Use this package when that distinction belongs in your data model. The polyfill does not install a global Temporal object. This guide uses the imported API, and its examples are documentation-based illustrations that have not been executed here.

Verdict

Choose @js-temporal/polyfill 0.5.1 when separate calendar dates, local date-times and exact timestamps make your application rules clearer. Start with one input boundary, set its overflow and time-zone policies, and check the resulting behavior in your own runtime before migrating the rest.

Answers from our run

@js-temporal/polyfill or luxon: which should you use?

luxon: Choose Luxon when common or custom parsing and formatting are your main requirement. Its README documents those formats alongside DateTime, Duration and Interval types. Choose @js-temporal/polyfill 0.5.1 when separate calendar dates, local date-times and exact timestamps make your application rules clearer.

When should you not use @js-temporal/polyfill?

The task is a few formatting calls on existing Date objects. Introducing a second date model creates conversion work that date-fns may let you avoid.

API stability3/5The 0.5 changelog records removal of Temporal.TimeZone, Temporal.Calendar and several convenience methods. The pinned declarations give a concrete API to target, but the package is still on a 0.x release line. Under the guide's rubric, explicit migration instructions make it usable while those documented removals keep this assessment at 3 rather than implying that old Temporal code needs no review.
Docs4/5The pinned README explains ESM and CommonJS usage, the lack of global installation, ES2020 output and the JSBI dependency. The accompanying declarations describe overflow and local-time disambiguation options, while the changelog names removed methods and replacements. That is enough for the boundary examples here. The Node floor differs between the README and package metadata, and the README delegates fuller teaching to external Temporal documentation.
Maintenance3/5Release 0.5.1 records a specific Node 23.x Intl.DurationFormat recursion fix and added Node 22.x and 23.x CI coverage. The preceding release records API updates and duration-calculation fixes. These are inspectable maintenance actions, supporting the rubric's middle assessment. No dated release-cadence or response-time evidence is included here, so this score does not claim recent activity, quick issue handling or a support commitment.
Ecosystem3/5The published 0.5.1 exports map includes import and require paths and bundled declarations, and the README explains its ES2020 and JSBI integration requirements. These are useful packaging provisions for JavaScript projects, with a real conversion cost where surrounding code expects native Date values. This assessment concerns integration facilities only; downloads, framework coverage and compatibility across a runtime matrix are not measured by this guide.

Use it if

  • You store birthdays or other calendar dates that should remain dates wherever the reader lives. Use PlainDate rather than giving those values a midnight timestamp.
  • A booking form collects a local date and time, and your application must decide what to do when a zone change makes that time ambiguous or nonexistent.
  • You need to keep an exact event timestamp separate from its display in a named time zone.
  • Your team wants Temporal types at application boundaries and can budget for explicit conversions to libraries that still take Date objects.
Skip it if

Setup reality

Install the reviewed version with npm install @js-temporal/polyfill@0.5.1, then import { Temporal } from '@js-temporal/polyfill'. The published exports map provides ESM and CommonJS entry paths plus TypeScript declarations. Its runtime dependency is JSBI. The package metadata says Node >=12, but the version-pinned README says Node.js 14 or later. Follow the stricter documented floor and verify your actual runtime rather than treating an engine declaration as a compatibility test. The README also says the distributed bundles contain ES2020 code; older targets need transpilation.

Importing the package leaves the global Temporal object alone. Keep the import consistent across your application. Before replacing an existing Date helper, identify what each value means: a date on a calendar, local date and time awaiting a zone, or an exact event timestamp. Moving strings between those meanings without a documented conversion merely moves the old ambiguity into new classes.

In 0.5.1, PlainDateTime.toZonedDateTime accepts a disambiguation option through ToInstantOptions. Choose 'reject' when a form should ask the user to resolve a missing or repeated local time. The default is 'compatible', so omitting the option is a policy choice too. A rejected conversion raises RangeError; catch that at the form boundary and offer a correction instead of letting a failed booking appear successful. Date-field assignment and date arithmetic have a separate overflow option, whose default is 'constrain'. Use 'reject' when silently clamping a day would violate your rules.

Read the 0.5 migration notes before copying older examples: Temporal.TimeZone and Temporal.Calendar were removed. The 0.5.1 notes report a fix for infinite recursion involving Intl.DurationFormat in Node 23.x and CI coverage for Node 22.x and 23.x. Those are the maintainers' release statements, not results from this guide. We inspected documentation, declarations and package metadata; we did not install the library, execute these snippets, run its test suite or measure application compatibility.

Ratings below use a documentation-based scale: 1 means serious documented obstacles, 3 means useful support with material caveats, and 5 means comprehensive support in the inspected area. Intermediate scores sit between those anchors. API stability considers documented breaking changes; docs quality considers setup and API coverage; maintenance considers recorded fixes; ecosystem considers package integration paths. None measures adoption or promises future support.

Patterns

Import the package API import-temporal

import { Temporal } from '@js-temporal/polyfill';

const date = Temporal.PlainDate.from('2026-11-02');
console.log(date.toString());

Import Temporal explicitly. This package does not install it globally; this and the remaining examples have not been executed here.

Keep a birthday as a calendar date represent-calendar-date

import { Temporal } from '@js-temporal/polyfill';

const birthday = Temporal.PlainDate.from('1990-06-15');
const stored = birthday.toString();
const restored = Temporal.PlainDate.from(stored);

PlainDate represents a calendar date independent of a time zone. Store it as a date in your application contract rather than assigning an arbitrary time.

Reject invalid form fields reject-invalid-fields

import { Temporal } from '@js-temporal/polyfill';

try {
  const date = Temporal.PlainDate.from(
    { year: 2026, month: 2, day: 30 },
    { overflow: 'reject' },
  );
  console.log(date.toString());
} catch (error) {
  if (!(error instanceof RangeError)) throw error;
  console.error('Choose a valid calendar date.');
}

Object-field assignment defaults to constrain. The explicit reject policy prevents an out-of-range field from being clamped into an accepted date.

Make month-end arithmetic a decision reject-month-overflow

import { Temporal } from '@js-temporal/polyfill';

const date = Temporal.PlainDate.from('2026-01-31');
try {
  const next = date.add({ months: 1 }, { overflow: 'reject' });
  console.log(next.toString());
} catch (error) {
  if (!(error instanceof RangeError)) throw error;
  console.error('Choose a month-end policy before continuing.');
}

Arithmetic defaults to constrain too. Reject raises RangeError for an out-of-range result; decide separately whether your billing rule should accept a shorter month's final day.

Sort calendar dates explicitly compare-calendar-dates

import { Temporal } from '@js-temporal/polyfill';

const dates = ['2026-11-03', '2026-11-01']
  .map(value => Temporal.PlainDate.from(value));
dates.sort(Temporal.PlainDate.compare);

Use the declared comparison function for date ordering. Keep all values in the same intended calendar model rather than relying on a formatted display string.

Resolve local input with a named zone resolve-local-time

import { Temporal } from '@js-temporal/polyfill';

const local = Temporal.PlainDateTime.from('2026-11-02T09:30');
try {
  const appointment = local.toZonedDateTime(
    'America/New_York',
    { disambiguation: 'reject' },
  );
  console.log(appointment.toInstant().toString());
} catch (error) {
  if (!(error instanceof RangeError)) throw error;
  console.error('Check the local time and time zone.');
}

ToInstantOptions defines reject for ambiguous or nonexistent local times. The sample date is ordinary input, not an executed transition test, and the application must decide how to ask for a correction.

Give an exact event a display zone display-event-in-zone

import { Temporal } from '@js-temporal/polyfill';

const event = Temporal.Instant.from('2026-11-02T14:30:00Z');
const display = event.toZonedDateTimeISO('America/New_York');
console.log(display.toString());

The declared conversion takes a time-zone identifier. Keep the event timestamp and the chosen display zone explicit in your application data.

Ask for a calendar-day difference difference-calendar-dates

import { Temporal } from '@js-temporal/polyfill';

const start = Temporal.PlainDate.from('2026-11-02');
const end = Temporal.PlainDate.from('2026-11-09');
const gap = start.until(end, { largestUnit: 'day' });
console.log(gap.days);

PlainDate.until returns a Duration and accepts calendar units. This example asks a calendar-date question, not how many elapsed hours separate two zoned events.

Serialize and restore an event timestamp roundtrip-event-string

import { Temporal } from '@js-temporal/polyfill';

const event = Temporal.Instant.from('2026-11-02T14:30:00Z');
const payload = JSON.stringify({ at: event.toString() });
const decoded = JSON.parse(payload);
const restored = Temporal.Instant.from(decoded.at);
console.log(restored.equals(event));

Instant declares string conversion, parsing and equality methods. Validate the surrounding JSON shape at the boundary; parsing a timestamp does not validate the rest of a request.

Alternatives

PackageRegistryPick it when
luxonnpmChoose Luxon when common or custom parsing and formatting are your main requirement. Its README documents those formats alongside DateTime, Duration and Interval types.
date-fnsnpmChoose date-fns when you want helpers around native Date values. Its README documents native dates and modular imports, so you can keep that existing data model.

More utils guides

lru-cache · type-fest · ajv · p-limit · zod · find-up · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.