Skip to content

Introduction

CSSzyx is a CSS-in-JS framework that compiles object-syntax Tailwind props to plain className strings at build time. An opt-in production step can then mangle those strings to hide the utility vocabulary — an obfuscation feature, not a size one: over a gzip-served app the arithmetic comes out flat or slightly negative, and the build reports the measured delta.

Traditional Tailwind usage has sharp edges:

// ❌ No type safety — typos silently produce no styles
<div className="p-4 bg-red-500 hover:bg-blue-600" />
// ❌ String concatenation is fragile
<div className={`p-4 ${isActive ? 'bg-blue-500' : 'bg-gray-200'} ${extraClass}`} />

CSSzyx solves this with object syntax:

// ✅ TypeScript catches invalid values at compile time
<div sz={{ p: 4, bg: 'red-500', hover: { bg: 'blue-600' } }} />
// ✅ Conditionals are natural JavaScript
<div sz={{ p: 4, bg: isActive ? 'blue-500' : 'gray-200' }} />
  1. Pre-scan — Walk source files at startup, write .csszyx/csszyx-classes.txt so Tailwind JIT can discover every sz-generated class name before compilation begins.

  2. JSX Transformsz={{ p: 4, hover: { bg: 'blue-500' } }}className="p-4 hover:bg-blue-500" (native engine). Also injects the @source directive into your CSS entry and auto-imports csszyx/lite runtime helpers where needed.

  3. Tailwind JIT — Reads .csszyx/csszyx-classes.txt, scans transformed className strings, generates CSS for every class in the build.

  4. Mangle (opt-in, production.mangle) — Builds the encode map p-4 → z, bg-blue-500 → y … using reversed tier-based encoding, then computes a SHA-256 checksum of the full map.

  5. Emit — Mangles CSS selectors and JS class strings in all output assets, then injects the checksum and mangle map into the HTML document.

Each phase is incremental. During dev, HMR updates .csszyx/csszyx-classes.txt when new sz props are added — no server restart needed.

The safelist is plain text, one class per line: Tailwind’s scanner reads any file as bytes, and parent-child CSS such as space-y-* or [&>span]:* comes from the class name, not from markup around it. With the Vite plugin, a safelist write is not a file the dev server can match to a module on its own, so csszyx tells it which modules the write affects — your Tailwind entry stylesheets, since they @source the file — and a class the project has never used before arrives as a CSS hot update. Component state, scroll position and open dialogs survive.

Zero Runtime

Static sz props compile to string literals. Nothing runs in the browser for the common case.

Type Safe

Auto-generated types from your Tailwind config. Invalid values are TypeScript errors, not silent bugs.

SSR Safety

SHA-256 checksums verify the mangle map matches between server and client. Mismatch triggers the abort protocol.

With production.mangle on (it is off by default), every Tailwind class is replaced by a short encoded symbol using reversed tier-based encoding (z → y → x → ...). The point is that the utility vocabulary is not readable in the shipped markup; it is not a smaller payload — see the caution in the config reference.

<!-- Development build -->
<div class="p-4 bg-blue-500 hover:bg-blue-600 rounded-lg text-white">
<!-- Production build -->
<div class="z y x a b">

The mangle map (z → p-4, y → bg-blue-500, …) is embedded in the HTML along with a SHA-256 checksum. The client runtime verifies this before hydrating.

  • Directorypackages
    • Directorycsszyx/ Umbrella — csszyx/vite, csszyx/webpack, csszyx/lite
    • Directorycompiler/ sz → Tailwind class transform (native engine + shared TypeScript lowering)
    • Directoryruntime/ _sz, _szMerge + SSR hydration guards
    • Directorycore/ Encoder, SHA-256 checksum, collision detection (Rust/WASM)
    • Directoryunplugin/ Unified plugin: Vite + Webpack + esbuild
    • Directorytypes/ Shared TypeScript types + JSX augmentation
    • Directorydynamic/ Runtime CSS injection via dynamic() for API/CMS-driven styling
    • Directoryvars/ CSS custom property helpers for runtime theming
    • Directorycli/ Migration CLI + type generator
    • Directorymcp-server/ Model Context Protocol server for AI assistants
    • Directoryvscode/ VS Code extension — IntelliSense, hover, diagnostics

The hot paths (encoding, checksum, collision detection) are implemented in Rust and compiled to WASM for performance. The compiler and runtime remain TypeScript for fast iteration.

CSSzyx targets Tailwind CSS v4 only. Tailwind v3 support is planned for a future release after the core is stable.