Skip to content

Plugin Config

CSSzyx is configured by passing options directly to the plugin. There is no standalone csszyx.config.ts file — all config lives in your bundler config.

vite.config.ts
import csszyx from 'csszyx/vite';
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
...csszyx({
development: {
debug: true,
},
production: {
mangle: true,
injectChecksum: true,
},
build: {
astBudgetLimit: 50_000, // optional, default 50k
cache: true, // optional, enabled by default
},
}),
tailwindcss(),
react(),
],
});
import type { PartialCsszyxConfig } from "@csszyx/types";
const csszyxOptions: PartialCsszyxConfig = {
exclude: ["src/generated/**"],
development: { debug: true },
production: { mangle: true },
};

Controls development mode behavior.

interface DevelopmentConfig {
strictMode: boolean; // Treat warnings as errors
debug: boolean; // Enable debug logging
}
OptionDefaultDescription
strictModefalseTreat all CSSzyx warnings as build errors
debugfalseEnable verbose debug logging

For per-element hydration recovery, use the szRecover JSX attribute on individual elements rather than a global flag — see SSR & Hydration → Recovery Tokens.

Controls production build behavior.

interface ProductionConfig {
mangle: boolean; // Minify class names (z, y, x, ...)
mangleVars: boolean; // Opt into dynamic sz CSS variable mangling and hoisting
mangleVarHoistMaxDepth: number; // Max cascade depth for mangleVars hoisting
mangleGlobalVars?: GlobalVarMangleConfig; // Explicit global token alias tier
contentHashing: boolean; // Hash for immutable caching
injectChecksum: boolean; // Add hydration checksum to HTML
incrementalBuild: boolean; // Enable build caching
minify: boolean; // Minify output
}
interface GlobalVarMangleConfig {
enabled: boolean;
mode?: 'alias';
tokens?: string[];
autoPrefix?: string;
onUnsafeUsage?: 'error';
reserved?: string[];
emitMap?: boolean;
}
OptionDefaultDescription
mangletrueReplace class names with short encoded symbols
mangleVarsfalseOpt into shorter names and bounded hoisting for dynamic CSS variables generated from runtime sz values. Disabled builds keep existing --_sz-* output.
mangleVarHoistMaxDepth5Maximum DOM ancestor distance for component-tier CSS variable hoisting when mangleVars is enabled.
mangleGlobalVarsundefinedOpt-in alias gate for explicit app-owned global CSS custom properties. Phase H v1 is alias-only and keeps original public variables defined.
contentHashingtrueHash CSS output for cache-busting
injectChecksumtrueEmbed SHA-256 checksum in HTML
incrementalBuildtrueCache build artifacts for faster rebuilds
minifytrueMinify emitted CSS and JS

mangleVars does not define global theme-token aliases. It only rewrites the dynamic CSS variables csszyx emits for runtime sz values, such as p: pad, and keeps the feature opt-in while the global token tier remains a separate design surface.

mangleGlobalVars enables the Phase H global token tier for explicit tokens. It is default-off, accepts only mode: 'alias', and must not remove original CSS custom-property names. autoPrefix remains disabled until csszyx can build the same alias table before source transforms and CSS output validation. Set emitMap: false only when the standalone .csszyx/global-var-map.json tooling asset is not needed; csszyx-manifest.json still includes globalVarAliases when aliases exist.

Controls the build pipeline.

interface BuildConfig {
buildId?: string; // Build identifier (auto-generated if omitted)
tailwindConfig?: string; // Path to Tailwind config file
outputDir?: string; // Output directory
cacheDir?: string; // Cache directory
cache?: boolean; // Enable per-file transform cache
astBudgetLimit?: number; // Max AST nodes per file before the transform skips it (warned)
parser?: "babel" | "oxc" | "rust"; // Source parser for JSX/TSX sz transforms
scanCss?: string | string[]; // CSS files with @theme blocks to auto-scan
}
OptionDefaultDescription
buildIdAutoUnique build identifier
tailwindConfig'tailwind.config.js'Tailwind configuration path
outputDir'.csszyx'Plugin output directory
cacheDir'.csszyx/cache'Incremental build cache
cachetrueEnable the per-file transform cache. Set to false when debugging parser output or isolating cache-related issues.
astBudgetLimit50000Max AST nodes per file before the transform gives up on it — guards against pathologically large generated files. A file past the cap is left unrewritten, contributes no classes to the safelist, and is warned about by every parser engine (the native rust engine included). The safelist prescan runs with a 10× cap by default so real page files keep their CSS; setting this applies your value to both lanes. Raise (e.g. 100_000) when a warning names a legitimate file, or exclude generated files via top-level exclude.
parser'rust'Source parser for JSX/TSX sz transforms. Default uses the native Rust engine through the matching optional @csszyx/core-* platform package; csszyx fails loudly when the package is missing. Set 'oxc' to opt into the previous JavaScript oxc-parser path on unsupported platforms or for parser-edge-case triage; 'babel' is the final compatibility escape hatch.
scanCssundefinedCSS files to scan for @theme blocks. Literal paths and simple globs are supported.

Use top-level include / exclude to control which source files csszyx parses. Filters accept literal paths, simple globs, or RegExp patterns. Excludes run before AST parsing, so large generated files can be skipped without hitting the AST budget.

csszyx({
exclude: ["src/generated/**", /icon-dump\.tsx$/],
});

csszyx hard-ignores /packages/ by default (a published library ships pre-extracted CSS) and pre-scans only the build root. In a monorepo, a design-system you author — whether under /packages/ or a sibling outside the build root — is source you want compiled. Opt it in by path:

csszyx({
compileSources: ["packages/vui", "../libs/ui"],
});

Paths resolve like Vite config paths: relative to the resolved project root (config.root, default the build cwd); absolute paths pass through. Each entry (a) exempts that directory from the ignore so its sz/szv is compiled, and (b) becomes a pre-scan root so its classes are safelisted. Symlinked workspace packages (pnpm) are matched after realpath resolution (relies on Vite’s default resolve.preserveSymlinks: false).

node_modules and .next stay ignored unless a listed path points into them. A /packages/ file with sz that is not under any compileSources directory is skipped silently (no CSS) — csszyx warns at build end and lists those files. A path that does not resolve to a directory is reported in a build warning.

A shared lib outside /packages/ (e.g. libs/ui) that lives inside the build root needs no config — it is compiled and scanned automatically; compileSources is only needed for /packages/ or for sources outside the build root.

Default true. In a monorepo, Tailwind v4’s automatic content detection climbs to the workspace root and scans sibling packages + docs (.md/.mdx/.txt are not ignored), which can generate phantom or broken url() classes and fail the build. When your Tailwind entry imports tailwindcss without scoping it (no source(none) / source(...) / @source not), csszyx warns once at build end with the two-line fix. Set false to silence that warning when a broad scan is intentional.

csszyx({
contentScopeCheck: false, // silence the unscoped-monorepo warning
});

See Monorepo & Content Scope for the full fix.

Default false. Set true to silence all csszyx build warnings — the skipped-sz, missing-Tailwind-entry, unscoped-content, unresolvable-spread, and safelist-cap messages. Useful when those warnings are understood and intentional, or to keep csszyx quiet while you focus on another tool’s output in the build log. Errors that abort the build (security / crash / build-break guards) still throw — only warnings are muted.

csszyx({
quiet: true, // silence every csszyx build warning
});

When set, the plugin parses @theme blocks in your CSS entry point and generates .csszyx/theme.d.ts — a declaration file that augments the CustomTheme interface in @csszyx/compiler. This surfaces custom design tokens (colors, spacing, fonts, radii, shadows) in sz prop IntelliSense without any manual type declarations.

vite.config.ts
...csszyx({
build: {
scanCss: 'src/index.css', // path to CSS with @theme blocks
},
})
src/index.css
@import "tailwindcss";
@theme {
--color-brand-500: #6d28d9;
--color-brand-600: #5b21b6;
--spacing-prose: 65ch;
--radius-card: 12px;
}

After the first build, .csszyx/theme.d.ts is generated. Add it to your tsconfig.json so TypeScript picks it up:

{ "include": ["src", ".csszyx/theme.d.ts"] }

Result: { bg: 'brand-500' } and { maxW: '--spacing-prose' } get full autocomplete and type-checking.

scanCss accepts a glob or array: ['src/index.css', 'src/tokens.css']. Theme files are watched in dev mode — hot-reload triggers type regeneration.

The same scan also registers your color, text-size, font-family, and font-weight tokens into szcn’s merge groups, so classes built from them dedupe correctly with zero extra wiring. This matters for semantic token names: with --color-warning and --color-danger scanned, szcn('text-warning', 'text-danger') keeps only the later class, while text-warning + text-sm co-exist (color vs size). Without the scan, szcn cannot tell warning is a color and safely keeps both. (Shade-shaped names like brand-500 classify by their {name}-{shade} shape alone and dedupe even unscanned.) Tokens from hand-written CSS outside @theme can be registered manually with registerSzcnGroups.

When scanCss is unset, the plugin still discovers @theme blocks on its own: it walks the project (and any compileSources packages) for CSS files carrying @theme and feeds their tokens to the szcn groups, so last-wins merging works with zero config. All @theme option keywords (inline, static, reference) are recognized. The auto-scan covers runtime merging only.csszyx/theme.d.ts type generation still requires an explicit scanCss, and setting one turns the auto-scan off in favor of exactly the files you listed.

Controls SSR hydration verification.

interface HydrationConfig {
strict: boolean; // Enable strict checks
defaultRecoveryMode?: "csr" | "dev-only"; // Default recovery mode
auditLog: boolean; // Log hydration events
}
OptionDefaultDescription
stricttrueAbort on any mismatch (non-configurable in production)
defaultRecoveryModenullNo recovery by default
auditLogtrueLog all hydration events

Controls performance optimizations.

interface PerformanceConfig {
parallel: boolean; // Parallel processing during build
workers?: number; // Worker thread count (auto-detected)
optimizeVariables: boolean; // CSS variable optimization
zeroRuntime: boolean; // Static optimization for zero-runtime cases
}
OptionDefaultDescription
paralleltrueProcess files in parallel using worker threads
workersAutoWorker count (defaults to CPU cores)
optimizeVariablestrueDeduplicate CSS custom properties
zeroRuntimetrueOptimize static sz props to literal strings