GitHub - meerita/FCSS2: Functional CSS: utility classes named after real CSS properties. One class, one declaration, zero runtime. Works with Vite, Next.js, Astro and Angular.
Pangram verdict · v3.3
We believe that this entire text is AI.
AI likelihood · overall
AIArticle text · 1,342 words · 1 segments analyzed
FCSS Utility CSS that reads like CSS. Install · Usage · Docs · npm FCSS is a utility CSS library where every class name is a CSS property and a value. If you know CSS, you already know FCSS. It works with any framework, or none. <div class="display--flex align-items--center gap--16 padding--24"> <p class="color--blue font-size--16 font-weight--bold">Hello, FCSS</p> </div> One class is one declaration: padding--24 is padding: 24px and nothing else. Names are the real CSS names, so it's background-color--blue, not bg-blue, and there is no cheat sheet to keep open. Hover, ARIA and breakpoint variants are part of the name (color--red:hover, display--block:aria-expanded:true, md-display--none). There is no runtime: the browser gets plain CSS, and your build removes the classes you don't use. Contents Requirements Installation: Vite · Next.js · Astro · Angular · Other bundlers (PostCSS) · Plain HTML / CDN Usage CLI Packages Documentation Requirements You need Notes Node.js 20.19+ or Bun Tested on Node.js 24 and Bun 1.4. Your framework may require a newer Node.js. A package manager: npm, pnpm, yarn or bun All four work. Examples show npm and bun; see the equivalents. A bundler or build step (recommended) To purge unused classes. Without one you can still use the CDN. Supported frameworks: Vite 5 – 8, Next.js 14 – 16, Astro 7, Angular 17 – 22. FCSS finds the classes you use by scanning HTML, JS/TS, JSX/TSX, Angular templates and .astro files. Vue (.vue) and Svelte (.svelte) files are not scanned yet, so a class used only there gets purged. Support is on the list. Package manager equivalents npm pnpm yarn bun npm install <pkg> pnpm add <pkg> yarn add <pkg> bun add <pkg> npm install -D <pkg> pnpm add -D <pkg> yarn add -D <pkg> bun add -d <pkg> npx fcss <command> pnpm exec fcss … yarn fcss … bunx fcss … npm run build pnpm build yarn build bun run build Installation Every setup has two parts. @functionalcss/core is the CSS itself: every class in every state and breakpoint, about 28 MB. Then a purge step, usually a framework integration, cuts that down to the classes your source actually uses, which is typically a few KB. You want both. Nobody should ship 28 MB of CSS, however good the gzip ratio looks. Platform Install Vite (React, Preact, Solid, vanilla JS/TS) npm install @functionalcss/core + npm install -D @functionalcss/vite Next.js npm install @functionalcss/core @functionalcss/next Astro npm install @functionalcss/core @functionalcss/astro Angular ng add @functionalcss/angular Other bundlers (PostCSS) npm install @functionalcss/core + npm install -D @functionalcss/postcss Plain HTML / CDN Nothing for a <link> tag; @functionalcss/cli to purge Vite (React, Preact, Solid, vanilla JS) npm install @functionalcss/core npm install -D @functionalcss/vite # or with bun bun add @functionalcss/core bun add -d @functionalcss/vite // vite.config.ts import { defineConfig } from 'vite'; import { fcss } from '@functionalcss/vite'; export default defineConfig({ plugins: [fcss()], }); // src/main.ts (your entry point) import '@functionalcss/core/full.css'; vite dev serves every class; vite build purges to what src/**/*.{html,js,jsx,ts,tsx} uses. Scan other paths with fcss({ config: { content: ['index.html', 'src/**/*.tsx'] } }) or an fcss.config.ts. Guide: React · package README. Next.js npm install @functionalcss/core @functionalcss/next # or bun add @functionalcss/core @functionalcss/next // next.config.ts import { withFcss } from '@functionalcss/next'; export default withFcss({ // your Next.js config }); // app/layout.tsx (App Router), or pages/_app.tsx (Pages Router) import '@functionalcss/core/full.css'; Next.js 16 builds with Turbopack by default; FCSS purges through webpack. Use "build": "next build --webpack" in package.json. next dev needs no flag. Next.js 14 and 15 need no changes. Guide: Next.js · package README. Astro npm install @functionalcss/core @functionalcss/astro # or bun add @functionalcss/core @functionalcss/astro // astro.config.mjs import { defineConfig } from 'astro/config'; import fcss from '@functionalcss/astro'; export default defineConfig({ integrations: [fcss()], }); --- // src/layouts/Layout.astro import '@functionalcss/core/full.css'; --- Works for static and server output; class="…" and static class:list entries are scanned. Guide: Astro · package README. Angular ng add @functionalcss/angular # in a bun workspace bunx ng add @functionalcss/angular The schematic installs the packages, adds the stylesheet to angular.json, and wires a purge step into your build script. Then: ng serve # development, every class available npm run build # production: purge first, then ng build (or: bun run build) Always build through npm run build; ng build on its own skips the purge. Guide: Angular · package README. Other bundlers (PostCSS) npm install @functionalcss/core npm install -D @functionalcss/postcss # or with bun bun add @functionalcss/core bun add -d @functionalcss/postcss // postcss.config.mjs import { createRequire } from 'node:module'; import fcss from '@functionalcss/postcss'; const require = createRequire(import.meta.url); export default { plugins: [ // The plugin purges on every run; this keeps the full set in development. process.env.NODE_ENV === 'production' && fcss({ manifest: require.resolve('@functionalcss/core/manifest.json'), content: ['src/**/*.{html,js,jsx,ts,tsx}'], }), ].filter(Boolean), }; Import @functionalcss/core/full.css from your entry point, and make sure your bundler runs PostCSS on CSS imported from node_modules. This path is used under the hood by the Vite, Next.js and Astro integrations; other bundlers have not been tested yet. Options: package README. Plain HTML / CDN No build step? Link the full stylesheet: <link rel="stylesheet" href="https://unpkg.com/@functionalcss/core/dist/full.css" /> This loads every class (about 28 MB), which is fine for prototypes but not for production. To ship only what you use, purge with the CLI: npm install @functionalcss/core npm install -D @functionalcss/cli npx fcss init --framework none # creates fcss.config.ts; point `content` at your HTML npx fcss purge -i node_modules/@functionalcss/core/dist/full.css -o public/fcss.css # same with bun bun add @functionalcss/core bun add -d @functionalcss/cli bunx fcss init --framework none bunx fcss purge -i node_modules/@functionalcss/core/dist/full.css -o public/fcss.css Run the purge again whenever your HTML changes. <link rel="stylesheet" href="/fcss.css" /> Usage Class syntax Pattern Example CSS property--value padding--24 padding: 24px property--value:pseudo color--red:hover :hover { color: … } property--value:aria-attr:value display--block:aria-expanded:true [aria-expanded='true'] { display: block } breakpoint-property--value md-display--none @media (min-width: 768px) { display: none } breakpoint-property--value:pseudo md-color--red:hover both combined <button class="padding--16 background-color--blue color--white border-radius--8 color--red:hover"> Save </button> <nav class="display--none md-display--flex justify-content--space-between">…</nav> Breakpoints are mobile-first (min-width): Prefix sm md lg xl xxl Min 576 px 768 px 992 px 1200 px 1400 px Colors are custom properties (--fcss-color-blue, …) defined in root.css, so you can re-theme them. Look up any class with npx fcss explain <class>, list them with npx fcss list, or see the reference. Keep class names static The purge step reads your source files; it cannot run your code. Write full class names: // ✅ found by the scanner <div className={isOpen ? 'display--block' : 'display--none'} /> // ❌ assembled at runtime, so it gets purged <div className={`display--${isOpen ? 'block' : 'none'}`} /> Classes you can't write statically go in the safelist. Configuration Optional fcss.config.ts at your project root (npx fcss init creates one): import { defineConfig } from '@functionalcss/cli'; export default defineConfig({ content: ['./src/**/*.{html,js,jsx,ts,tsx}'], safelist: ['display--none', 'display--block'], }); Custom classes Multi-declaration, project-specific rules use the c- prefix and live in your own CSS: .c-card { display: flex; flex-direction: column; border-radius: 8px; padding: 16px; } CLI npm install -D @functionalcss/cli # or: bun add -d @functionalcss/cli Command Description fcss init [-f <framework>] Create fcss.config.ts and add the CSS import fcss purge -i <in.css> -o <out.css> Keep only the classes found in your content globs fcss audit Flag dynamic class fragments and deprecated classes fcss explain <class> Show what a class compiles to fcss list [-p <property>] List classes for a property or category fcss build Generate custom CSS (colors, data states) from your config fcss doctor Check your installation fcss migrate Migrate from legacy TFCSSF class names Packages Package What it is @functionalcss/core The CSS library and class manifest @functionalcss/vite Vite plugin (purge + dev diagnostics) @functionalcss/next Next.js plugin @functionalcss/astro Astro integration @functionalcss/angular Angular ng add schematic @functionalcss/postcss PostCSS purge plugin (used by the integrations) @functionalcss/cli fcss command-line tool @functionalcss/scanner Source scanner (for building your own tooling) @functionalcss/spec Machine-readable specification @functionalcss/generator CSS generator All published on npm under @functionalcss. Editor support (VS Code and Zed extensions, LSP server) lives in this repo and is not published yet. Documentation Installation · Syntax · Responsive · States · Purging · Custom CSS · Reference · Migration · Philosophy Contributing See CONTRIBUTING.md for setup, architecture, and contribution guidelines. License MIT © Diego Lafuente