Skip to content

Core API

Proxy-based chainable style builder. The recommended way to write styles.

import { tw } from 'typewritingclass'
tw.bg('blue-500').p(4).rounded('lg').shadow('md')
tw.flex.flexCol.relative.truncate

Single-utility modifiers (property syntax)

Section titled “Single-utility modifiers (property syntax)”

The modifier applies to the next utility in the chain:

tw.hover.bg('blue-500')
tw.md.p(8)
tw.dark.bg('slate-900')
tw.hover(tw.bg('blue-500').textColor('white').shadow('lg'))
tw.dark(tw.bg('slate-800').textColor('slate-100'))

Resolves to a class string automatically:

<div className={tw.p(4).bg('blue-500')} />
tw.p(4).toString()
tw.p(4).value
tw.p(4).className

Every chain is immutable — property access and method calls return new chains:

const base = tw.flex.flexCol
const a = base.gap(4) // flex + flexCol + gap(4)
const b = base.gap(8) // flex + flexCol + gap(8)
tw nameMaps to
tw.contentcontent_()
tw.floatfloat_()
tw.staticstatic_()
tw.placeholderplaceholder_ modifier
tw.selectionselection_ modifier
tw.hashas_() modifier

Composes style rules and string class names into a single CSS class string.

function cx(...args: (StyleRule | string)[]): string

Later arguments override earlier ones via CSS layer ordering.

import { cx, p, bg, rounded } from 'typewritingclass'
cx(p(4), bg('blue-500'), rounded('lg'))
// => "_a1b2c _d3e4f _g5h6i"
// Mix with plain strings
cx('my-class', p(4), bg('white'))
// With modifiers
cx(p(4), when(hover)(bg('blue-600')), when(md)(p(8)))

Like cx() but also returns an inline style object for dynamic CSS values.

function dcx(...args: (StyleRule | string)[]): { className: string; style: Record<string, string> }
import { dcx, bg, p, dynamic } from 'typewritingclass'
const { className, style } = dcx(p(4), bg(dynamic('#e11d48')))
// className => "_a1b2c _d3e4f"
// style => { '--twc-d0': '#e11d48' }
<div className={className} style={style} />

Applies modifiers (pseudo-states, breakpoints, dark mode) to style rules.

function when(...modifiers: Modifier[]): (...rules: StyleRule[]) => StyleRule

Modifiers are applied right-to-left (first modifier is innermost):

when(hover)(bg('blue-600')) // :hover
when(md)(p(8)) // @media (min-width: 768px)
when(hover, md)(bg('blue-700')) // hover inside md breakpoint
when(dark)(bg('slate-900'), textColor('white')) // dark mode

Escape hatch for raw CSS declarations.

// Object form
css({ display: 'grid', 'grid-template-columns': '1fr 1fr' })
// Tagged template
css`
display: flex;
align-items: center;
gap: 0.5rem;
`
// With dynamic values
const color = dynamic('#e11d48')
dcx(css`background-color: ${color}; padding: 1rem;`)

Wraps a value for runtime CSS custom property injection.

function dynamic<T extends string | number>(value: T): DynamicValue<T>

Use with dcx() — the value becomes a var(--twc-dN) reference in CSS and is applied via inline style:

const { className, style } = dcx(bg(dynamic(color)))
<div className={className} style={style} />

Type guard for DynamicValue. Useful when building custom utilities:

function isDynamic(v: unknown): v is DynamicValue

Assigns explicit layer priority, overriding automatic layer numbering:

function layer(priority: number): (...rules: StyleRule[]) => StyleRule
const base = layer(0)(p(4), bg('white')) // low priority, easily overridden
cx(base, bg('blue-500')) // blue overrides white

Low-level functions for building custom utilities. See Writing Utilities.

createRule({ padding: '1rem' })
createDynamicRule({ color: 'var(--twc-d0)' }, { '--twc-d0': '#ff0000' })

Returns the full CSS string for all registered rules. Used by the compiler and SSR integrations:

function generateCSS(): string

interface StyleRule {
_tag: 'StyleRule'
declarations: Record<string, string>
selectors: string[]
mediaQueries: string[]
supportsQueries: string[]
dynamicBindings?: Record<string, string>
selectorTemplate?: string
}
interface DynamicValue<T = string | number> {
_tag: 'DynamicValue'
__value: T
__id: string
}
interface DynamicResult {
className: string
style: Record<string, string>
}
type Utility = (value: any) => StyleRule
type Modifier = (rule: StyleRule) => StyleRule
TypeAccepted valuesUsed by
ColorInputTheme tokens, CSS color strings, dynamic()bg(), textColor(), borderColor()
SpacingInputNumbers (spacing scale), CSS strings, dynamic()p(), m(), gap() and variants
SizeInputNumbers, CSS strings, size tokens, dynamic()w(), h(), size(), minW(), etc.
RadiusInputRadius tokens, CSS strings, dynamic()rounded() and variants
ShadowInputShadow tokens, CSS strings, dynamic()shadow()