Your look is captured as typed tokens
Loom reads your code and writes your design decisions as tokens in the DTCG 2025.10 format, the first stable version of the design tokens standard. Each value carries its evidence: where in your code it came from. Values Loom cannot convert are listed for a person to decide, never guessed. Partial
What works today: a primitive tier and a semantic tier in one valid file. What does not work yet: the component tier and modes for themes and brands are in development; build outputs for CSS variables, Tailwind and CSS-in-JS are planned.
Loom keeps your token names. It maps each token to a tier and a role. Renames happen only through a proposal your team accepts.
On our copy of Story Atelier, the service added a primitive tier: 58 role tokens now alias 54 primitives, every name was kept, and all 69 original custom properties resolve to exactly the same values. Working That work was done on our copy and the founder has not yet accepted the records.
The same button. A new structure underneath.
The base button rule of takenote, an open-source notes app (MIT), before and after conversion. After conversion, the same rule reads the tokens Loom generated for it. Move the slider: the rule converts value by value, and the look stays the same.
%buttons {
border: 2px solid $primary;
border-radius: 0.3rem;
background: $primary;
color: white;
font-weight: 600;
font-size: 1rem;
padding: 0.5rem 0.75rem;
margin: 0 0 0.5rem 0;
line-height: 1;
}
.button {
border: 2px solid var(--semantic-action-primary);
border-radius: 0.3rem; /* no token yet */
background: var(--semantic-action-primary);
color: var(--palette-gray-10);
font-weight: 600;
font-size: 1rem;
padding: var(--space-3) 0.75rem; /* 12px: off scale */
margin: 0 0 var(--space-3) 0;
line-height: 1;
}
What each token resolves to, in the generated file
var(--semantic-action-primary)→{proto.primary}→#5183f5needs a human decisionvar(--palette-gray-10)→#ffffffneeds a human decisionvar(--space-3)→8pxneeds a human decision
Token names, values and statuses are copied from the token file Loom’s conversion generated for takenote (24 October 2026). The after rule was written by hand for this page from those names; rewriting stylesheets automatically (codemods) is a concept.
Every component has one contract
A contract is one record per component: purpose, when to use it and when not to, anatomy, API, states, behaviour, accessibility and content rules. Conversion drafts a contract for every component it finds, and marks every gap as a question for your team. Working
For Story Atelier, conversion drafted 81 contracts and listed 192 open questions. A contract starts as a scaffold. Your team answers the questions; Loom does not invent the answers.
This is what a finished contract records. It is a real one from Loom Base, our own open-source system, read when this page is built.
One contract: Switch
Loom Base 1.0.0, MIT- Purpose
- Turns a single setting on or off, taking effect immediately.
- When not to use it
- The choice is only applied after pressing Save: use Checkbox.
- Choosing between more than two options: use RadioGroup.
- States
- off, on (off → on, on → off); flags: disabled
- Keyboard and role
- Space, Tab · role
switch, the same on native - Tested behaviour
- 10 scenarios, run on web and native from this one file
| Component token | Resolves through | Value | |
|---|---|---|---|
track.background:checked | semanticcolor. | primitivecolor. | #1e2a78 |
track.border-color | semanticcolor. | primitivecolor. | #716856 |
root.min-height | semanticsize. | primitivesize. | 24px |
packages/base/contracts/switch.contract.json and the token files when this page is built, so it always matches the code.Components written and checked before review
Loom writes a component for React and React Native from one contract, then checks it before a person reviews it: axe on every state, keyboard and focus scripts, and parity between the two platforms. Partial
What works today: Button, Switch and Dialog, with 50 of 50 parity scenarios passing (28 on web, 22 on native). What does not work yet: writing a client's own components this way; visual regression checks; native tests on real devices (they run in a simulated environment today). A person always gives the final approval. Partial
One contract, two platforms
Diagram- Reactwritten from the contract
- React Nativewritten from the contract
- axe
- keyboard
- parity tests
Nothing is ready until it meets the definition of ready
A component is ready when its contract is complete, its automated checks pass, both platforms behave the same, and a named person has approved it. Loom prepares and checks. Your team decides.
Rules are written so that agents can follow them
Conversion writes an agent package: an AGENTS.md file plus rules generated from your system. For Story Atelier that is 251 rules. Working
Content rules, such as banned phrases, preferred terms and patterns for interface copy, are rule records that Loom checks in compositions, in code and from the command line. Working
Visual brand rules and a managed illustration library are in development. Concept Localisation readiness is checked in part: the audit checks four readiness items today. Partial What does not work yet: pseudo-localisation runs and text-expansion checks per locale.
The look is kept, and the proof is measured
The owner's rule: a key screen may differ by at most 0.5% of its pixels after conversion, and a person reviews anything flagged. Loom compares before and after screenshots against that rule and shows each change in colour. Partial
What does not work yet: taking the screenshots automatically for every key route, and migrating your products with codemods and agent pull requests. Migration as pull requests with before and after screenshots is a concept. Concept
Prototypes are built from your real system
If a design system does not let you prototype, test and explore ideas quickly, it is not doing its job. Compose a screen and Loom builds a clickable prototype from your system's own components, checked against its rules as you go. Partial
What works today: the composer builds pages from system components for our reference system, on a development server. What does not work yet: other systems, and prototypes that an agent builds from a written brief.
Storybook stories come from the contracts
Loom generates Storybook stories from component contracts. For our reference system, 733 stories render in a real browser. Partial What does not work yet: stories for a client's own system.
A team without a system starts from Loom Base
A team with no design system starts from Loom Base, our own system. Loom themes it from your app's own colours and type, prunes it to what your app uses, and writes a migration plan. You own the result from day one. Partial What does not work yet: it has run on one pilot app so far.
A design system should be a tool your teams use, not a manual they consult. Shape makes it one.
Questions
Will our product look different? No. Conversion keeps the look. The 0.5% rule and a person's review make that measurable.
Do we have to use React? Today Loom writes React and React Native. The audit reads React, TypeScript, CSS and plain HTML apps. Other stacks are candidates, not built.
Who answers the open questions in the contracts? Your team, with our experts. Loom lists the questions and the evidence; people decide.
Do we have to rename our tokens? No. Loom maps your names to tiers and roles. A rename is a proposal, with migration, only if your team wants it.