Skip to content

Vite Plugin

The Vite plugin statically extracts styles at build time into optimized CSS with full HMR support.

Terminal window
bun add typewritingclass
bun add -d typewritingclass-compiler
vite.config.ts
import { defineConfig } from 'vite'
import twcPlugin from 'typewritingclass-compiler'
export default defineConfig({
plugins: [twcPlugin()],
})

Add your framework plugin alongside it (React, Solid, Svelte, Vue, etc.):

plugins: [react(), twcPlugin()]

Import once in your entry file:

// src/main.ts or src/main.tsx
import 'virtual:twc.css'

If TypeScript complains, add a declaration:

src/vite-env.d.ts
/// <reference types="vite/client" />
declare module 'virtual:twc.css' {}
twcPlugin({
strict: true, // default: true -- errors on non-static cx() args
})

See Strict Mode for details.

  1. Theme loading — imports theme modules and passes them to the Rust compiler.
  2. Transform — for each .ts/.tsx/.js/.jsx file with typewritingclass imports, the Rust compiler extracts styles and replaces calls with class name strings.
  3. CSS generationvirtual:twc.css collects all extracted rules, deduplicates, orders by layer, and returns the final CSS.
  4. HMR — file changes invalidate the virtual module. The browser receives updated CSS without a full reload.

Generated automatically via MagicString. DevTools trace CSS rules back to the original TypeScript source file and line.

  • Errors appear in Vite’s browser overlay and fail production builds.
  • Warnings appear in the terminal.
DiagnosticCause
Cannot statically evaluate argumentA cx() arg is a variable. Wrap in dynamic() or disable strict mode.
Unknown utility functionUnrecognized function inside cx().
Property conflict detectedSame CSS property set multiple times in one cx() call.

If the compiler fails on a file, the original source is preserved and typewritingclass/inject is prepended for runtime fallback.