One design system.
Every ecosystem.
Describe your design system once, as DTCG design tokens. Transtyle compiles it into native, idiomatic themes for eleven ecosystems today — shadcn/ui, daisyUI, Apache ECharts, Bootstrap, Storybook, Radix Themes, PrimeNG, Mantine, Chakra UI, Material UI, and plain CSS variables. Deterministic. Explainable. Zero runtime.
Alpha On npm as @transtyle/cli@alpha — published so it
can be tried, not because it is finished.
Read A compiler for design systems — the experiment, the architecture, and what four real design systems look like coming out of it.
$ npx transtyle build shadcn bootstrap echarts
shadcn 39% native · 53% derived · 8% dropped
↳ dist/shadcn/globals.transtyle.css
bootstrap ↳ dist/bootstrap/_variables.transtyle.scss
echarts ↳ dist/echarts/theme.acme-{light,dark}.json
↳ report.json — provenance for every value
✔ build complete — rebuilds are byte-identical - Targets
- 11
- Live demos
- 44
- Rebuilds
- byte-identical
- Runtime
- none
A compiler, not a converter
The architecture of Babel and LLVM, applied to design systems: pluggable frontends and backends around one intermediate representation. N sources and M targets cost N+M mappings, not N×M converters.
You writetoken files · importers
One source of truth: your names, your values, plain JSON any token tool can read.
Transtyle compilesone shared representation
validate · explain
Your tokens bind once to the semantic catalog — a pivot vocabulary of meanings, not names. Gaps are filled by deterministic rules.
You shipnative themes · exporters
Idiomatic files per ecosystem — plus a coverage report saying how faithful each one is.
Author three tokens — or every single one.
Three is not a marketing number: a brand color, a page background and a text color are the decisions that make a theme yours, and CI compiles exactly that design system against all 11 exporters on every commit. The floor is one token: leave the page and its text out and they default to white and near-black, swapped in dark mode.
The derivation engine fills every slot you didn't author — hover states, on-colors, tints, dark-mode wiring, a data-viz palette — with deterministic, versioned rules. But every one of those slots is a real, addressable token: the catalog exposes the full role grids, elevation ladder, and scales, so you can pin any value — down to a single dark-mode hover state — and derivation yields to you. Authored always wins; every value knows its origin.
You write
{
"semantic": {
"color": {
"primary": { "solid": { "$value": "{option.color.blue.600}" } },
"elevation": { "0": { "surface": { "$value": "{option.color.white}" } } },
"text": { "base": { "$value": "{option.color.gray.900}" } },
"border": { "base": { "$value": "{option.color.gray.200}" } }
}
}
} You get derived
--primary: oklch(0.55 0.18 255);
--primary-foreground: oklch(1 0 0); /* contrast-picked, 4.9:1 */
--accent: oklch(0.95 0.017 255); /* brand-tinted */
--chart-1: #026fd7; /* hue-rotated palette */
/* …plus every hover/active state, light + dark,
for all eleven targets, from the same tokens */ Ask the compiler why: npx transtyle explain primary.tint prints the value's full provenance chain.
Same tokens. Native everywhere.
This is the whole product in one picture: one token definition on the left, and what each ecosystem's components look like wearing it. Not screenshots — these previews are styled with the actual compiled Acme values.
tokens/semantic.tokens.json
{
"semantic": {
"color": {
"primary": {
"solid": { "$value": "{option.color.blue.600}" }
},
"danger": {
"solid": { "$value": "{option.color.red.600}" }
}
},
"radius": {
"md": { "$value": "0.5rem" }
}
}
} Those previews are a summary. The 44 live demos are the real thing — each target's own components, in the browser, consuming only the compiled dist/.
Don't take our word for it — 44 of them are running
Four design systems, each compiled to all 11 targets and deployed. Within a target the page is byte-identical, so everything that changes between these columns came out of the compiler. The swatches below are read from a live compile at build time.
One meaning, every dialect
Frameworks disagree on names, not needs. The catalog slot is the meaning; each exporter speaks its target's dialect natively. Your danger, everywhere:
danger.solid--destructiveshadcn/ui$dangerBootstrap Sass--color-errordaisyUI--danger-9Radix ThemesdangerseverityPrimeNG preset
The full pivot vocabulary is one page: the Transtyle language. Your own names stay yours — you bind them once, with one-line aliases.
Honest about lossiness
Translation between ecosystems is lossy. Transtyle doesn't hide it — it measures it. Every build classifies every variable, so trust is a number, not a vibe.
Acme on shadcn: 15 native · 20 derived · 0 approximated · 3 dropped, of 38 variables.
Every exporter is a plugin
The core knows nothing about Bootstrap. All 11 official exporters use the same public plugin API — resolve the catalog, emit native files, report coverage honestly. The css-variables exporter is the reference implementation to copy from; the internals guide documents the contract.
Built for humans and agents
Deterministic builds, config-as-data, stable diagnostic codes, and a JSON report per build make Transtyle operable by AI agents end-to-end — while the compiler itself stays rule-based and auditable. Agents write config; the compiler compiles it.
Start compiling
On npm as @transtyle/cli@alpha. Prefer to look before you install? The four examples in the repository compile end to end, two of them real systems nobody here designed (GOV.UK, Carbon).
npm i -D @transtyle/cli
npx transtyle init # config + starter tokens
npx transtyle add bootstrap # …or shadcn, echarts, storybook, …
npx transtyle build