TypeScript-native
Utilities are functions, not string conventions. Full autocomplete, type checking, and refactoring support out of the box.
TypeScript-native
Utilities are functions, not string conventions. Full autocomplete, type checking, and refactoring support out of the box.
Two functions
cx() to compose, when() to modify. That’s the entire API surface.
Everything else is just utilities and modifiers slotting into these two
shapes.
Zero runtime
The compiler extracts all static styles at build time. No runtime CSS generation, no style injection, no FOUC. Just plain CSS files.
Dynamic when needed
Wrap runtime values with dynamic() and use dcx() — the compiler emits
CSS custom properties and a tiny runtime handles the rest.
import { cx, p, bg, rounded, when, hover, md } from 'typewritingclass'import { blue } from 'typewritingclass/theme/colors'import { lg } from 'typewritingclass/theme/shadows'
const className = cx( p(4), bg(blue[500]), rounded('lg'), when(hover)(bg(blue[600])), when(md)(p(8)),)The compiler extracts this into static CSS at build time:
@layer l0 { ._a1b2c { padding: 1rem; }}@layer l1 { ._d3e4f { background-color: #3b82f6; }}@layer l2 { ._g5h6i { border-radius: 0.5rem; }}@layer l3 { ._j7k8l:hover { background-color: #2563eb; }}@layer l4 { @media (min-width: 768px) { ._m9n0o { padding: 2rem; } }}Every utility and modifier follows the same two type signatures. Custom plugins slot in identically to built-ins — no registration, no configuration, just import and use.
// A utility: takes a value, returns a StyleRuletype Utility = (value: any) => StyleRule
// A modifier: takes a StyleRule, returns a StyleRuletype Modifier = (rule: StyleRule) => StyleRuleThis means your custom glow() utility composes with the built-in when(hover) exactly the same way bg() does.