Zubra docs

Browser support#

Zubra targets browsers with Baseline 2026 features: everything Baseline Widely available, plus the features below. When a newer feature is used, it's used only where the browser has it.

The runtime keeps a fallback for each feature that isn't Widely available:

  • moveBefore() isn't in Safari (Limited availability);
  • ElementInternals.states (for :state(hydrated)) became Baseline in 2024, so it isn't Widely available yet: where it's missing, the host just doesn't get the state;
  • no browser ships TC39 Signals.
Feature Used for Without it
Custom elements, shadow DOM, <template>, ES modules Everything Not supported
Declarative shadow DOM (<template shadowrootmode>) Server-rendered shadow components Not supported
ElementInternals (form-associated custom elements) form-associated components Not supported
Constructed stylesheets (adoptedStyleSheets) Shadow component styles, adoptStyles() Not supported
CSS @scope (Baseline since December 2025) Light-DOM component styles stopping at slotted content A light-DOM component's <style> doesn't apply; shadow components are unaffected
CSS cascade layers Putting component styles under utilities and page CSS Not supported
Element.moveBefore() (Chromium, Firefox; not Safari) Keyed list moves that keep focus and iframe state Used where present; otherwise rows move with insertBefore
Processing instructions and <template for> (Chrome, Edge 150+) Hydration markers; streamed regions placed without JavaScript Parsed as comments, which the runtime reads the same way; an inline script places streamed regions
TC39 Signals (not shipped anywhere yet) Reactivity The runtime's own implementation (runtime/src/signal-impl.js)

The policy: a major version targets the Baseline year of its release, and drops fallbacks for features that are Widely available by then.

The browser suites run in Chromium. CI also runs the runtime's browser suite and the React and Vue example apps in Firefox and WebKit (Safari's engine), through Playwright. The counting of live objects in the leak suite needs Chromium's DevTools protocol, so it runs in Chromium only.

Known engine issues:

  • Firefox before 159 can apply a light-DOM component's <style> to content slotted into it, when that content sits beside the component's own elements of the same kind. Firefox shares styles between siblings that differ only in an attribute an @scope rule depends on (bug 2075194, fixed in 159). Shadow components are unaffected.
  • Firefox logs "The invalid form control … is not focusable" when a form with an invalid Zubra control won't submit. It's only a message: Firefox does focus the input inside (the validation anchor), as Chromium and WebKit do, and the form is refused. form.reportValidity() logs nothing.
  • WebKit clears long lists more slowly relative to building them than Chromium does (2,000 rows cleared in about 2.8× the time of creating 1,000). It isn't the quadratic case the benchmark guards against, so the ratio checks run in Chromium only.

Edit this page on GitHub · Zubra 5.0.3