Instant UI state updates. ZERO React re‑renders. <1 KB runtime.
Pre‑render your UI once, flip a data-* attribute to update — that's it.
| Interactive menu with render tracker | Main Demo↗ | Compare Zero‑UI vs. React side‑by‑side while toggling a menu. | Github |
| React benchmark (10 000 nested nodes) | React 10k↗ | How long the traditional React render path takes. | Github |
| Zero‑UI benchmark (10 000 nested nodes) | Zero‑UI 10k↗ | Identical DOM, but powered by Zero‑UI's data-* switch. | Github |
Every setState in React triggers the full VDOM → Diff → Reconciliation → Paint pipeline. For pure UI state (themes, menus, toggles) that work is wasted.
Zero‑UI introduces "PRE‑rendering":
- Tailwind variants for every state are generated at build‑time.
- The app pre‑renders once.
- Runtime state changes only flip a data-* attribute on <body>.
Result → 5-10× faster visual updates with ZERO additional bundle cost.
| 10,000 | ~50 ms | ~5 ms | 10× |
| 25,000 | ~180 ms | ~15 ms | 12× |
| 50,000 | ~300 ms | ~20 ms | 15× |
Re‑run these numbers yourself via the links above.
Prerequisite: Tailwind CSS v4 must already be initialized in your project.
That's it — the CLI patch‑installs the required Babel & PostCSS plugins and updates configs for you.
Then follow Setup → for your bundler.
-
Spread bodyAttributes on <body> in your root layout.
// app/layout.tsx import { bodyAttributes } from '@austinserb/react-zero-ui/attributes'; // or: import { bodyAttributes } from '../.zero-ui/attributes'; export default function RootLayout({ children }) { return ( <html lang="en"> <body {...bodyAttributes}>{children}</body> </html> ); } -
Add the PostCSS plugin (must come before Tailwind).
// postcss.config.js module.exports = { plugins: { '@austinserb/react-zero-ui/postcss': {}, tailwindcss: {} } };
- key → becomes data-{key} on <body>.
- defaultValue → optional, prevents FOUC.
- Note: the returned staleValue does not update (useUI is write‑only).
Any data-{key}="{value}" pair becomes a variant: {key}-{value}:.
- useUI → writes to data-* attributes on <body>.
- Babel plugin → scans code, finds every key/value, injects them into PostCSS.
- PostCSS plugin → generates static Tailwind classes at build‑time.
- Runtime → changing state only touches the attribute — no VDOM, no reconciliation, no re‑paint.
- Zero React re‑renders for UI‑only state.
- Global setters — call from any component or util.
- Tiny: < 1 KB gzipped runtime.
- TypeScript‑first.
- SSR‑friendly (Next.js & Vite SSR).
- Framework‑agnostic CSS — generated classes work in plain HTML / Vue / Svelte as well.
- UI state only → themes, layout toggles, feature flags.
- Business logic stays in React → fetching, data mutation, etc.
- Kebab‑case keys → e.g. sidebar-open.
- Provide defaults to avoid Flash‑Of‑Unstyled‑Content.
PRs & issues welcome! Please read the Contributing Guide.
MIT © Austin Serb
Built with ❤️ for the React community. If Zero‑UI makes your app feel ZERO fast, please ⭐️ the repo!
.png)



