An open specification for component contracts
The source of truth is neither the design file nor the code.
A design system's truth should live in a machine-readable contract that sits between the surfaces and generates both. This is the working spec for that contract — vendor-neutral, deterministic, and open — with a reference implementation that proves every claim it makes.
New here and not sure what this does? Get started is organised by what you want: a component on the canvas that you want as code (A), components in code that you want in Figma (B), or a mature library on both sides that you want reconciled (C).
Four positions, held together
A growing category of tools speaks this vocabulary; this project holds four positions that, together, none of them do.
Bidirectional
The contract generates both the code and the design canvas, and imports from both — round-trips are proven, not promised.
Deterministic
Every artifact is computed from file data and byte-pinned; no LLM guesses in the pipeline (AI is available as an assistant, never as an authority).
Receipted
Anything the pipeline cannot carry is named on screen — a gap is reported, never papered over with a plausible value.
Open
The schema, the engine, and every instrument that verifies them are in one repository under one permissive license, with no gated tier — because a spec the community can't fully use isn't a spec.
The model
Every organization that takes design systems seriously eventually splits into two camps. Some come in from the code side: the system is an npm package, and the design files are an aging picture of it. Others come in from the design side: the system is a canvas library, and the code is an approximation of the pictures. Both camps are answering the same question — where does the truth live? — and both answers fail the same way: whichever surface is declared canonical, the other becomes a hand-maintained copy. Copies drift. Drift erodes trust.
The rule that makes it work: surfaces never sync side-to-side. An engineer's new prop and a designer's color change take the same path — flagged by the differ, promoted into the contract as a reviewable diff, then regenerated out to the other surface. One arbiter, version-controlled, no arbitration meetings. It's the governance model that made Git work for code and the DTCG token format work for design tokens, run one level up — at the component-API layer.
How it works — three questions, answered with the engine running →
What a contract looks like
One small, versioned JSON document per component: props and their legal values, anatomy, token bindings, slot constraints, accessibility semantics, declared events. This excerpt is a shipping contract from the reference implementation — the same file generates the typed React component and the canvas component set, and a three-way differ proves both keep matching it.
{
"id": "ds.banner",
"name": "Banner",
"version": "1.0.0",
"props": [
{
"name": "status",
"description": "Feedback tone — drives the color scheme, the leading icon, and the ARIA role (error/warning announce as alerts).",
"type": {
"enum": [
"info",
"success",
"warning",
"error"
]
},
"default": "info",
"bindings": {
"figma": {
"kind": "VARIANT",
"property": "Status",
"values": {
"info": "Info",
"success": "Success",
"warning": "Warning",
"error": "Error"
}
},
"code": {
"prop": "status"
}
}
}
],
"anatomy": {
"root": {
"tokens": {
"max-width": "{size.banner.width}",
"background-color": "{color.feedback.{status}.background}",
"color": "{color.feedback.{status}.foreground}",
"border-radius": "{radius.banner.{container}}",
"gap": "{space.gap.control}",
"padding-inline": "{space.inset-x.md}",
"padding-block": "{space.inset-y.lg}"
}
}
}
}One file; two faithful renderings; a differ that can mechanically prove both. Every field is specified in the reference — generated from the schema itself, so the docs cannot drift from the spec.
The proof, counted
in contracts/
one pipeline, both surfaces
(
npm run eval)react · html · react-inline · figma
the coverage receipt
(the census)
Counted from the repository at build time — contracts, tokens, and the emitter registry are read, not quoted; instrument numbers come from the committed reports they cite.
What it does, and what that costs — the pair
Those counts are about this repository. The question an adopter actually asks is what the tool does to their library, and that has two halves which are only honest together. What it does: 54 components from 6 third-party libraries score 89.6% mean computed-style equality against the original package rendering (exact string match, no tolerance, 379,861 cells), and in the other direction a Figma kit converts to code at 92.70% over 537 scored variants. What that costs: those 54 components are 6.0% of the 893 in the libraries they came from, and they were picked because they were the tractable ones.
Three doors in
Read the Spec
Every schema branch, with constraints, refusal rules, and real shipping contracts as examples.
Try the Playground
The actual engine in your browser: import from Figma or code, edit under governance, watch refusals by name.
Get started
Organised by what you want to do: canvas into code, code into Figma, or both-already-exist reconciled. Real commands, and the structural limits stated up front.