One import
import { tw } from 'typewritingclass' — chain utilities, modifiers, and
shorthands off a single object. Full autocomplete, zero config.
One import
import { tw } from 'typewritingclass' — chain utilities, modifiers, and
shorthands off a single object. Full autocomplete, zero config.
TypeScript-native
Utilities are functions, not string conventions. Full autocomplete, type checking, and refactoring support out of the box.
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 { tw } from 'typewritingclass'
const card = tw.p(4).bg('blue-500').rounded('lg').hover.bg('blue-600').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) => StyleRule