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.
What is statically evaluable?
Section titled “What is statically evaluable?”| Expression | Static? |
|---|---|
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 variable | No |
isActive ? bg('blue') : bg('gray') | No |
Fixing strict mode errors
Section titled “Fixing strict mode errors”Use dynamic() for runtime values
Section titled “Use dynamic() for runtime values”import { dcx, bg, dynamic } from 'typewritingclass'
function Card({ color }: { color: string }) { const { className, style } = dcx(bg(dynamic(color))) return <div className={className} style={style} />}Inline known values
Section titled “Inline known values”// Before (error):const size = 4cx(p(size))
// After:cx(p(4))Predefine variants
Section titled “Predefine variants”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} />Disabling strict mode
Section titled “Disabling strict mode”// VitetwcPlugin({ strict: false })
// esbuildtwcEsbuildPlugin({ 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.
When to disable
Section titled “When to disable”- Migrating a large codebase incrementally.
- Rapid prototyping.
- Library code that passes parameters through to consumers.