Skip to content

Strict Mode

Strict mode (enabled by default) ensures all style arguments can be statically evaluated at build time. If the compiler encounters a value it cannot resolve, it reports an error rather than silently falling back to runtime injection.

ExpressionStatic?
p(4), bg('blue-500'), rounded('lg')Yes
tw.p(4).bg('blue-500')Yes
when(hover)(bg('blue-600'))Yes
dynamic(color)Yes (explicit opt-in)
p(spacing) where spacing is a variableNo
isActive ? bg('blue') : bg('gray')No
import { dcx, bg, dynamic } from 'typewritingclass'
function Card({ color }: { color: string }) {
const { className, style } = dcx(bg(dynamic(color)))
return <div className={className} style={style} />
}
// Before (error):
const size = 4
cx(p(size))
// After:
cx(p(4))
const variants = {
primary: tw.bg('blue-500').textColor('white'),
danger: tw.bg('red-500').textColor('white'),
} as const
// No error -- picking a precomputed string
<span className={variants[variant]} />

Use separate class strings for conditionals

Section titled “Use separate class strings for conditionals”
const compact = tw.p(2)
const spacious = tw.p(6)
<div className={isCompact ? compact : spacious} />
// Vite
twcPlugin({ strict: false })
// esbuild
twcEsbuildPlugin({ strict: false })
// Babel
{ "plugins": [["typewritingclass-babel", { "strict": false }]] }

Even with strict mode off, the compiler still extracts everything it can statically. Non-static arguments fall back to runtime.

  • Migrating a large codebase incrementally.
  • Rapid prototyping.
  • Library code that passes parameters through to consumers.