@functionalcss/vite
v0.1.3
Published
FCSS Vite plugin — source scanning, production purge, and dev diagnostics
Readme
@functionalcss/vite
Vite plugin for FCSS — adds production CSS purging and development dynamic-fragment warnings for React+Vite projects.
Features
- Production purge — removes unused FCSS utility classes at build time (via PostCSS AST, not regex).
- Dev diagnostics — warns when dynamic template literals in
classNameprevent static analysis. - HMR support — triggers full reload when
fcss.config.tschanges. - No runtime JS — zero FCSS code is added to the browser bundle.
Installation
npm install @functionalcss/core @functionalcss/vite -DSetup
vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { fcss } from '@functionalcss/vite';
export default defineConfig({
plugins: [react(), fcss()],
});fcss.config.ts
import type { FcssViteConfig } from '@functionalcss/vite';
const config: FcssViteConfig = {
content: ['src/**/*.{ts,tsx}', '!node_modules/**'],
};
export default config;src/main.tsx
import '@functionalcss/core/full.css';Options
| Option | Type | Description |
| ----------------- | -------------------------------------- | ------------------------------------------------------------------------------------ |
| config.content | string[] | Glob patterns pointing to source files. Defaults to src/**/*.{html,js,jsx,ts,tsx}. |
| config.safelist | Array<string \| { pattern: RegExp }> | Classes to always keep, regardless of whether they appear in source. |
Static class pattern
FCSS relies on static analysis. Use string literals or class maps — not template literals:
// ✅ Correct: static class map
const stateClass: Record<string, string> = {
active: 'opacity--1',
inactive: 'opacity--0.5',
};
<div className={stateClass[isActive ? 'active' : 'inactive']} />
// ✅ Correct: static string
<div className="display--flex padding--16" />
// ❌ Wrong: template literal prevents static analysis
<div className={`display--flex opacity--${isActive ? '1' : '0.5'}`} />The plugin warns about dynamic fragments in dev mode and purges those classes in production.
Dynamic class map pattern
For conditional classes, use an explicit map object:
const buttonVariant: Record<'primary' | 'ghost', string> = {
primary: 'background-color--black color--white',
ghost: 'background-color--white color--black',
};
<button className={buttonVariant[variant]}>{label}</button>;Production purge report
When vite build runs, the plugin logs a purge summary:
[@functionalcss/postcss] Purge: 17/326313 selectors retained (326296 removed, 100.0% reduction, ...)Peer dependencies
vite ^5.0.0 || ^6.0.0@functionalcss/core(for the CSS and manifest)
