Quick Start
The tw API
Section titled “The tw API”Everything chains off a single import:
import { tw } from 'typewritingclass'Chain utilities to build styles. Design tokens are accessed as properties — no strings needed:
<div className={tw.p(6).bg.white.rounded.lg.shadow.md} />Property-access tokens
Section titled “Property-access tokens”Colors, border radius, shadows, font sizes, font weights, and layout enums are all available as properties:
tw.bg.blue500 // background-color: #3b82f6tw.textColor.slate900 // color: #0f172atw.rounded.lg // border-radius: 0.5remtw.shadow.md // box-shadow: ...tw.text.lg // font-size + line-height presettw.font.bold // font-weight: 700tw.items.center // align-items: centertw.justify.between // justify-content: space-betweentw.cursor.pointer // cursor: pointerColor tokens support opacity via callable syntax:
tw.bg.blue500(50) // background-color: rgb(59 130 246 / 0.5)Value-less utilities
Section titled “Value-less utilities”Utilities that take no arguments are accessed as properties:
tw.flex.flexCol.gap(4)tw.relative.overflow.hiddentw.italic.truncateModifiers
Section titled “Modifiers”Access a modifier as a property and it applies to the next utility:
tw.bg.white.hover(tw.bg('blue-50'))tw.p(4).md.p(8).lg.p(12)tw.bg.white.dark(tw.bg.slate900)For multiple utilities under one modifier, call it as a function:
tw.hover( tw.bg.blue500 .textColor.white .shadow.lg)Complete example
Section titled “Complete example”import { tw } from 'typewritingclass'
// Card containerconst card = tw.group .p(6) .bg.white .rounded.xl .shadow.md .hover(tw.shadow.lg.scale(102)) .dark(tw.bg.slate800)
// Title responds to group hoverconst title = tw .textColor.slate900 .font.bold .groupHover(tw.textColor.blue600) .dark(tw.textColor.white)
// Responsive layoutconst container = tw .flex.flexCol .gap(4) .md(tw.flex.gap(8))
function Card() { return ( <div className={card}> <h2 className={title}>Hello, typewritingclass</h2> </div> )}Arbitrary values
Section titled “Arbitrary values”You can always pass raw CSS values as string arguments:
tw.bg('#ff6347').rounded('0.625rem').shadow('0 4px 12px rgba(0,0,0,0.15)')Immutable chains
Section titled “Immutable chains”Every access returns a new chain. The original is never mutated:
const base = tw.flex.flexColconst withGap4 = base.gap(4) // flex + flexCol + gap(4)const withGap8 = base.gap(8) // flex + flexCol + gap(8)// base is still just flex + flexColDynamic values
Section titled “Dynamic values”For runtime values (props, state, user input), use the functional API with dcx() and dynamic():
import { dcx, bg, p, rounded, dynamic } from 'typewritingclass'
function Banner({ color }: { color: string }) { const { className, style } = dcx(p(6), bg(dynamic(color)), rounded.lg) return <div className={className} style={style}>Welcome!</div>}Alternative: cx() + when()
Section titled “Alternative: cx() + when()”The tw chain and the functional cx()/when() API are interchangeable and produce identical CSS. Standalone utilities also support property-access tokens:
import { cx, p, bg, rounded, when, hover } from 'typewritingclass'
cx(p(4), bg.blue500, rounded.lg, when(hover)(bg.blue600))Both APIs can coexist in the same project. Use whichever reads better for each situation.