refract v0.1 · beta
Reference / Performance

Performance & footprint

refract compiles a realistic theme in about a millisecond and the core + CSS adapter weigh ~36 KB gzipped — or nothing at all if you emit CSS at build time. The numbers below are measured and reproducible; treat them as order-of-magnitude, since they scale with your theme's size and your hardware.

Method — reproduce it yourself. npm run bench times createTheme + theme.css and override() (median of 400 runs in V8 / Node) against this site's richest preset — 177 recipe classes, 112 @media rules. npm run size reports the gzip footprint against a committed budget (gated in CI). Both live in scripts/. A typical app theme is smaller and faster.

Runtime footprint

The browser bundle is core + the CSS adapter (the runtime graph the showcase itself loads):

What shipsSize
Runtime bundlecore ~28 KB gzip · + CSS adapter ~8 KB gzip (measured, npm run size)
Build-time delivery0 KB — emit CSS to a file, <link> it, and refract never reaches the client (see Build-time)

Compile cost

createTheme plus reading the full theme.css — the entire compile — on that heavy theme:

OperationCost
createTheme() + theme.css~1.2 ms median — fast enough to run on page load or per request
override(delta) + .css~0.8 ms median (reuses the base — only the delta recompiles)

override() is cheaper because it's a delta merge with structural sharing — only the changed subsystem slices re-normalize, everything else keeps its reference. That's the number behind the "delta merge, not a re-run" claim, and why spinning up many brand children off one base is close to free.

Emitted CSS size

Per preset — the stylesheet a browser actually downloads:

MetricValue
theme.css~27 KB raw · ~3.8 KB gzip
contents177 recipe classes · 112 @media rules

Emitted CSS scales with recipes × conditions (states / breakpoints / containers), not with the number of tokens — tokens are just :root variables. A leaner recipe set emits proportionally less.

The Playground shows the same instrumentation live — tokens · classes · KB — recomputed as you edit, so you can watch cost move with your theme.

Browser support

The emitted CSS targets modern evergreen browsers — roughly Baseline early 2023 (Chrome/Edge 111+, Firefox 113+, Safari 16.4+). The features it leans on:

FeatureWhere it's used · floor
:where()zero-specificity recipe selectors — widely available since 2021
@layeroptional cascade layer for the emitted output (opt-in) — Chrome 99 / Firefox 97 / Safari 15.4
prefers-color-schemethe modes dark/light blocks (media realization) — widely available since 2019
@containeronly when you declare containers — Chrome 105 / Firefox 110 / Safari 16
oklch()opt-in only (colorFormat: "oklch") — default output is rgb(), so the floor doesn't move unless you ask for it. Chrome 111 / Firefox 113 / Safari 15.4

Skip container queries and keep the default rgb() colour format and the floor drops further — the tokens themselves are plain custom properties, supported everywhere. Nothing here needs a polyfill or a build-time downlevel; the OKLCH colour math runs at build time and emits ordinary rgb(), so it costs the browser nothing.

Output stability

Emitted output is a stable contract across patch and minor releases: the same theme compiles to byte-identical CSS — same --<prefix>-… variable names, same class names, same rule order — so you can snapshot-test the emitted stylesheet and bind downstream code to the names. A change to an emitted name or the output structure is a breaking (major) change, called out in the release notes; opt-in features are byte-identical when off. This complements the token-path stability guarantee — the format-neutral identity (the token path) and the rendered name are both treated as public API.

Technical documentation for @theme-registry/refract · all output is compiled client-side by the real library (CSS adapter). The chrome is theme-aware; the render panes carry each preset's own world. · MIT licensed.