refract v0.1 · beta
Reference / Project status

Project status

refract is beta. Here's what that means concretely — what you can build on from day one, what's still moving, and what's next.

Where refract comes from

refract didn't start as a library. It started as the infrastructure behind a flagship site and ~130 sister sites that shared one administration and one foundation — each differing in little more than its colour palette and logo, none allowed to drift in look and feel. Frontends were Next.js + styled-components on a shared CMS-backed admin, templates loaded lazily, one style-guide driving them all. That pattern — one base theme, many brands, override only what's yours — went on to run a multi-brand media group, a pan-European NGO network, and a multi-identity civic institution.

Those estates ran on a UI-focused theme registry (previously under an earlier npm scope, now consolidating under @theme-registry): a main theme plus child themes that override whatever they need. What it never standardized were the foundations — layout (grids, columns, spacing), the media model, and colour/type synthesis, solved well but ad-hoc. refract is those foundations, taken from what worked, made solid and format-neutral, and made to show their work (diffTheme blast radius, WCAG audit) before anything ships.

What the lineage proves — and doesn't. The design (author → override → runtime-or-prebuilt, foundations included) is battle-tested across real multi-brand estates: a flagship + ~130 regional sites on one shared infrastructure; a multi-brand media group with per-brand child overrides side by side; a pan-European NGO federation, override-per-member at federation scale; and a multi-identity civic institution, distinct identities on one platform without forking. The idea has the better part of a decade of production behind it; the published package is new — a clean, standardized rewrite that earns its own miles. Client names are withheld — the credibility is in the shapes, not the logos.

Tested & gated

Beta doesn't mean untested. refract ships with a real safety net: 760 tests across 66 files (unit · golden-output · integration), and every push to main runs five gates in CI — a green run is a precondition for merge and for the docs deploy. The counts and budgets on this page are drift-gated against a live compile, so they can't quietly go stale.

CI gateWhat every push must pass
Buildpnpm -r build — every package compiles
Typecheckpnpm -r typecheck — no tsc errors across the monorepo
Testpnpm -r test — the full 760-case suite
Docs driftdocs:validate — every documented error message, emitted name, perf figure, and the counts above are checked against the live library
Size budgetpnpm run size — the gzip footprint stays under a committed ceiling (below)

Size budget gzip · CI-enforced

Each published surface carries a committed gzip ceiling in size-budget.json; a regression that pushes past it fails the build. The runtime you actually ship to a browser is core + one adapter — everything else is build-time only, or nothing at all if you emit CSS ahead of time.

PackageBudget (gzip)
@theme-registry/refract runtime core≤ 30 KB
@theme-registry/refract-css≤ 9 KB
@theme-registry/refract-styled-components≤ 6.5 KB
@theme-registry/refract/dtcg interop subpath≤ 4.5 KB
@theme-registry/refract-scss≤ 4 KB
@theme-registry/refract-json≤ 3 KB
Measured footprint and compile cost — always under these ceilings — live in Performance & footprint. Reproduce everything yourself: npm run bench (compile timings) and npm run size (gzip vs budget), both in scripts/.

Stability

Two statuses. Stable: breaking changes are deliberate, announced events — safe to build on. Experimental: the shape may still change; pin your version and expect some churn.

SurfaceKindStatusDocs
RawThemethe input formatCoreStableRawTheme anatomy
Theme runtimecreateTheme · tokens · resolveToken · overrideCoreStablecreateTheme & Theme
Adapter contractdefineAdapter · AdapterSpec · BoundSpec · RenderContextCoreStableWriting an adapter
Token pathsthe format-neutral path per token — adapters render it into namesCoreStableToken paths & naming
CSS adapteroutputs a CSS stylesheetAdapterStableCSS adapter
SCSS adapteroutputs Sass sourceAdapterExperimentalSCSS adapter
JSON adapteroutputs a JSON token documentAdapterExperimentalJSON adapter
styled-components adapteroutputs TS/JS theme modulesAdapterStableSC adapter
DTCG interopDTCG token import + exportInteropStableDTCG interop
MCP serverlive theme queries for AI agentsToolingStableMCP server

In short: core, the CSS and styled-components adapters, DTCG interop, and the MCP server are stable at public release — the authoring format, the theme runtime, the adapter contract, the emitted names, and the agent query surface. The SCSS and JSON adapters are still settling.

Versioning

refract and its adapters version in lockstep: all six packages share one version through the whole 0.x line — a single Changesets fixed group that publishes together — so a matched set is always safe to install. Stability tiers are signalled by an npm dist-tag, not by divergent versions: the stable packages ride latest, the SCSS and JSON adapters are reachable via the experimental tag. Pin exact versions through 0.x; at 1.0 the fixed group splits into independent lines (core on its own 1.x). Full policy: RELEASING.md. One guarantee already holds: token paths are stable identifiers — a path won't change or vanish within a minor/patch release, so agents and DTCG documents can bind to it (see Token paths & naming).

What “beta” means here, plainly. Frozen within 0.x: token paths and emitted output (same theme → byte-identical CSS). Still moving: the SCSS/JSON adapter shapes and the “What's next” items below. At 1.0 the public contract — RawTheme grammar, REFRACT_E_* codes, manifest schema, adapter contract — becomes semver-stable and the lockstep group splits. Every release is recorded in the CHANGELOG; the full policy is in RELEASING.md.

What's next

  • A default starter theme. A complete, ready-to-use design system in a separate @theme-registry package — a full styleguide you don't have to build, but format-agnostic: export it through any available adapter (CSS · SCSS · JSON · styled-components), or through one you write yourself. It also becomes the shared basis for this site's examples and playground presets.
  • Contrast audit shipped — the opt-in refract audit command (and programmatic audit(theme)) scores every palette basetext and recipe fg/bg pairing against WCAG 2 (with an advisory APCA Lc). It reports by default; --strict fails the run. See Contrast audit.
  • Logical properties / RTL planned — a logical: true output option (padding-inline, border-inline-start, side: "start" | "end") so themes mirror for right-to-left for free.
  • Compound variants planned — a multi-axis matcher (size × tone × shape) so combinations resolve automatically instead of by hand-enumeration.
  • Multi-source external tokens planned — borrowing from two prefixed parent systems in one theme via named sources (single-source external ships today).
Building on refract today? Lean on the Stable surfaces; treat the Experimental ones as likely to shift, and pin your version.
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.