Caveats: Browser Compatibility & Polyfill Requirements

Espalier is designed around a core principle: build to browser standards, not around them. We adopt modern platform APIs as they reach specification maturity, even when some browsers have not shipped implementations yet. This keeps the library dependency-free and ensures that polyfills are dropped the moment native support lands — without requiring a library update or a major version bump.

This page documents every area where consuming applications may need to provide a polyfill or account for a compatibility boundary.


Temporal API

What It Is

The Temporal API is the TC39 Stage 3 replacement for JavaScript's long-broken Date object. It provides immutable, timezone-aware types (PlainDate, PlainTime, PlainDateTime, PlainYearMonth) that make calendar arithmetic correct and predictable.

Where Espalier Uses It

Espalier relies on the global Temporal namespace in two components:

  • <esp-date-picker> — All date parsing, calendar grid generation, range selection, min/max validation, and display formatting use Temporal.PlainDate, Temporal.PlainYearMonth, and related types.
  • <esp-input type="date"> — Date validation (min, max, format parsing) uses Temporal.PlainDate.

What Happens Without It

<esp-date-picker> performs a runtime check for window.Temporal. If the namespace is missing, the component renders an inline error message instead of the calendar UI:

Temporal API not found. Load the polyfill in <head> before using <esp-date-picker>.

<esp-input type="date"> will fail to validate date constraints if Temporal is unavailable.

What You Need To Do

Load the @js-temporal/polyfill (or any spec-compliant polyfill) before your application code runs. The recommended approach is a <script> tag in your document <head>:

<head>
  <script src="https://cdn.jsdelivr.net/npm/@js-temporal/polyfill/dist/index.umd.js"></script>
  <!-- or bundle it with your application -->
</head>

If you use a bundler, install it as a production dependency of your application:

npm install @js-temporal/polyfill

Then import it at your application's entry point, before any Espalier imports:

import { Temporal } from "@js-temporal/polyfill";
// Assign to globalThis so Espalier can find it
globalThis.Temporal = Temporal;

import "@taprootio/taproot-controls";

When You Can Remove It

The Temporal API is at Stage 3 and shipping in Firefox 139+ and Safari 26+. Once your target browsers support it natively, remove the polyfill — no changes to Espalier are required.


OKLCH Color Notation

What It Is

OKLCH is the perceptually uniform color model that Espalier uses for all internal color logic. The oklch() CSS function is supported in all major browsers since 2023.

Relative Color Syntax

Espalier also uses Relative Color Syntax — the oklch(from ...) form — to derive hover states, active states, and theme variants mathematically from a base color:

background: oklch(from var(--esp-color-primary) calc(l + 0.05) c h);

This syntax is used across 9 source files in the library and is fundamental to the theming engine.

Browser Support

Feature Chrome Firefox Safari
oklch() 111+ 113+ 15.4+
oklch(from ...) 119+ 128+ 18+

Relative Color Syntax became Baseline in December 2024. If you must support browsers older than those listed above (particularly Firefox 127 or earlier), you will see incorrect or missing colors.

What You Need To Do

There is no JavaScript polyfill for CSS color functions. Ensure your supported browser matrix includes the versions listed above. For enterprise deployments with managed browser policies, this typically means:

  • Chrome/Edge 119+ (released October 2023)
  • Firefox 128+ (released July 2024)
  • Safari 18+ (released September 2024)

Custom Elements and Shadow DOM

Espalier uses the standard Custom Elements v1 and Shadow DOM v1 APIs. These are supported in all modern browsers and do not require polyfills.

If you need to support legacy browsers that lack custom element support (IE11, older Edge), the webcomponentsjs polyfills can be loaded. However, Espalier does not test against polyfilled environments and cannot guarantee full functionality.


ElementInternals and Form Association

Espalier form controls (<esp-input>, <esp-pick-one>, <esp-checkbox>, etc.) use ElementInternals for native form participation — setting form values, managing validity, and participating in form submission and reset.

ElementInternals is supported in Chrome 77+, Firefox 98+, and Safari 16.4+. No polyfill is required for any browser released after April 2023.


CSS Features

Beyond OKLCH, Espalier uses several modern CSS features:

Feature Minimum Browser Version Notes
Container Queries Chrome 105+, Firefox 110+, Safari 16+ Used for responsive component sizing
CSS Nesting Chrome 120+, Firefox 117+, Safari 17.2+ Used in component stylesheets
:host / :host() All modern browsers Shadow DOM styling
clamp() Chrome 79+, Firefox 75+, Safari 13.1+ Fluid typography

All of these are Baseline features with broad support. If your deployment environment restricts browser versions, the highest bar is CSS Nesting (Chrome 120+, December 2023).


Summary of Consumer Responsibilities

Requirement Action Can Be Removed When
Temporal polyfill Install @js-temporal/polyfill and load before Espalier All target browsers ship native Temporal
OKLCH Relative Color Enforce minimum browser versions in your support matrix Already Baseline; no action if targeting 2024+ browsers
CSS Nesting Enforce Chrome 120+ / Firefox 117+ / Safari 17.2+ Already Baseline; no action if targeting late-2023+ browsers

The Philosophy

Espalier intentionally does not bundle polyfills or transpile modern CSS. This is a deliberate architectural choice:

  1. Zero unnecessary weight. Polyfills for features your users already have are dead code.
  2. Clean removal. When a standard ships everywhere, you delete the polyfill from your app. No library update, no breaking change, no migration guide.
  3. Forward compatibility. Espalier's code is the code browsers will run natively. There is no abstraction layer to rot.

Espalier is a bedrock design system. It builds to where the platform is going, and it trusts you to bridge the gap for the browsers you actually need to support today.

Where does this show?