A design system compiler.
Describe your design system once, in design tokens.
Compile native themes for every ecosystem you ship in.
Documentation · Live demos · npm · Roadmap · Vision
Warning
Alpha — experimental. Breaking changes ship without a deprecation cycle: token vocabulary, generated output, config format and CLI surface can each change between alpha releases. Pin an exact version, and treat generated files as disposable output you regenerate — never as something to hand-edit and keep. (why)
"Our brand color is #4f46e5" is one decision. In a real product it lives in a Bootstrap Sass
variable, a --primary in shadcn's globals.css, a JSON key in an ECharts theme, and a knob in
Storybook's manager — maintained four times, by hand, and drifting apart from the day they are
written.
Transtyle makes it one input and many outputs:
tokens.json ─────→ transtyle build ─────→ dist/shadcn/globals.transtyle.css
your names, dist/bootstrap/_variables.transtyle.scss
your values, dist/echarts/theme.<name>-{light,dark}.json
plain DTCG JSON …one directory per target
+ usage.md + report.json
Every output is an idiomatic file a developer of that framework would recognize. Nothing you ship depends on Transtyle at runtime.
npm install # link workspaces (compiler packages have zero external dependencies)
cd examples/acme
npx transtyle build # compile every configured target
npx transtyle check # the pipeline without emit: validation + contrast + coverageOr in your own project:
npm i -D @transtyle/cli@alpha
npx transtyle init # scaffold config + starter tokens
npx transtyle add bootstrap
npx transtyle buildEight exporters ship today:
| Target | Emits |
|---|---|
| shadcn/ui | globals.css — light + dark, both Tailwind eras |
| Bootstrap | _variables.scss + _maps.scss, or the CSS-variable path |
| daisyUI | two @plugin "daisyui/theme" blocks, light + dark, OKLCH |
| Apache ECharts | theme JSON, one per mode, with a derived series palette |
| Storybook | manager + preview theme |
| Radix | 12-step color scales + alpha variants, for Radix Themes or standalone |
| PrimeNG | an Aura-based preset, severities and component archetypes |
| css-variables | plain custom properties — also the reference plugin implementation |
The core knows nothing about any of them: every one is a plugin on the same public API, so a third-party exporter is a package name in your config.
The mental model is Babel's, or LLVM's:
importers (frontends) intermediate representation exporters (backends)
───────────────────── ─────────────────────────── ────────────────────
DTCG token files ┐ ┌→ Bootstrap (Sass + CSS vars)
Figma variables ├──→ normalized, derived, ───┼→ shadcn/ui (globals.css)
Tailwind config ┘ validated token graph ├→ Apache ECharts (theme JSON)
└→ …
One source of truth in the middle, pluggable ends on either side — which is what makes ecosystem-to-ecosystem translation (Bootstrap → shadcn/ui) a composition of parts rather than a special feature. Importers are specced, not yet built; today the frontend is DTCG.
Four properties hold it up:
- DTCG superset, not a proprietary format. Sources are valid W3C design tokens plus namespaced extensions, so Style Dictionary, Tokens Studio and Figma interoperate for free (ADR-0002).
- Deterministic, explainable derivation. You author the handful of decisions you actually made; every other slot is filled by inspectable rules.
transtyle explain <slot>prints the chain that produced a value (derivation). - Honest about lossiness. Each build reports what mapped natively, what was derived, what was approximated, and what the target cannot express (coverage).
- Regeneration is byte-deterministic. Same tokens, same files — so the output belongs in a build step, not in review.
Four examples compile end to end, each with runnable demo projects under
examples/<name>/demo/<target>/ that consume only the compiled output:
| Example | What it shows |
|---|---|
| Acme | the ordinary case — a small brand, every target |
| Cathode | a hostile one — a dark-native CRT system with its own vocabulary, bound by one-line aliases |
| GOV.UK | a real published system, adopted without renaming anything |
| Carbon | IBM's, likewise — real values, real accessibility constraints |
All 32 of those demos (4 examples × 8 targets) are deployed and browsable: transtyle.github.io/transtyle/demo. Within a target the page is byte-identical across all four design systems — enforced in CI — so anything that differs between them came out of the compiler. Each demo has a switcher in the corner for jumping along either axis.
To run them locally instead:
npm run dev -w acme-demo-bootstrap # the same page in real Bootstrap, port 4101
npm run dev -w acme-demo-shadcn # …and in real shadcn/ui, port 4103
npm run dev -w cathode-demo-storybook # a phosphor-green Storybook, port 6201
npm run demos:all # build all 32 + the site, exactly as deployedbuild, check, explain, init, add and diff are implemented; import, preview and
version pinning are specced. The component tier — theming components, not just palettes — is live
on Bootstrap and PrimeNG. ROADMAP.md is the authority on what is real versus planned;
docs/findings/ records what needed a judgment call.
User documentation is on the website (npm run site:dev
to run it locally): getting started, concepts, configuration, CLI, exporter guides, diagnostics, a
guide to driving Transtyle with AI agents, and a
blog. The site also serves llms.txt and every page as raw markdown.
Engineering documentation lives in docs/:
| Area | Documents |
|---|---|
| Why / what | VISION.md, prior art, naming |
| Architecture | overview, pipeline, IR, derivation, plugins, versioning |
| Specifications | configuration, CLI, validation & coverage, doc generation, component layer, exporters |
| Decisions | docs/adr/ |
| Process | CONTRIBUTING.md, RELEASING.md |
Transtyle (transpile × style): a source-to-source compiler for design systems, and the name says so. Selection history and rejected candidates: docs/naming.md.
MIT.