Adoption
Roll Cronwerk UI into an existing product incrementally — theming setup, font strategy, versioning, and keeping drift out.
Incremental adoption
You do not have to rewrite anything. Cronwerk is designed to land one surface at a time:
- Tokens first. Import
@cronwerk/tokens/tokens.cssand start replacing ad-hoc colors, spacing, and radii with the CSS variables. Nothing visual changes until you opt a surface in — but new work now speaks the language. - Leaf components next. Swap in
Button,Chip,Card, and inputs where you already have equivalents. They are self-contained and carry their own styles via@cronwerk/ui/styles.css. - Zones, then pages. Move whole sections onto
Paneland the layout primitives once the leaves feel right. Reserve the halftone accent panel for the one statement moment per page.
Theming setup
Theming is one attribute: data-theme="dark" on <html> (light is the default,
so no attribute means light). The mechanics:
- Pre-paint snippet (
@cronwerk/tokens/theme-init.js) setsdata-themebefore first paint from the sharedcronwerk-themelocalStorage key — inline it in<head>to avoid a flash. - Runtime toggle: wrap the tree in
ThemeProviderfrom@cronwerk/ui/themeand calltoggleTheme()(or usegetTheme/setThemefrom@cronwerk/tokens). The key is shared across every Cronwerk property, so a user’s choice follows them between apps. - Dark theme comes free for canvas,
Card, and neutral/softPanel. The accent panel stays orange in both themes by design.
Font strategy
Fonts are the consumer’s responsibility (the tokens only name the families). Two supported routes:
- Bundle with Fontsource (
@fontsource-variable/inter,@fontsource-variable/jetbrains-mono) — best for apps that control their build. Self-hosted, no third-party requests. - Self-host the woff2 files and declare
@font-faceyourself if you already have a font pipeline. Match the family names the tokens expect (Inter Variable,JetBrains Mono Variable) or override--font-sans/--font-mono.
Prefer preloading the primary text font (Inter) for a fast LCP; the tokens set
font-display behavior at the consumer layer.
Versioning & the public API
Each package is versioned independently with semver. What counts as a breaking change:
- Token names are public API. Renaming or removing a
--tokenis a MAJOR bump (LIBRARY-SPEC §9) — values can shift within reason, names cannot. - Component props follow normal semver: additive props are MINOR, removed or retyped props are MAJOR.
Pin ranges accordingly and read the changesets before a major upgrade.
Do
Consume tokens through the CSS variables (var(--accent)) so a value change
flows in automatically.
Don't
Don’t hard-copy a token’s hex into your code — you opt out of theming and every future value fix.
Keeping drift out
Once adopted, keep the surface honest. The repo ships a drift audit
(pnpm drift:audit) that flags hard-coded values that should be tokens, and an
adoption report (pnpm adoption:report) that tracks how much of each consumer is
on the language. Wire them into your own CI as you migrate.