Common questions and answers about React Zero-UI
Everything you need to know to get the most out of Zero-UI.
React Zero-UI is a state management library that eliminates React re-renders for UI state by using CSS and data attributes instead of component state. It "pre-renders" all possible UI states at build time and switches between them by flipping data attributes.
Traditional React:
const [theme, setTheme] = useState("light");
// Every setState() triggers re-render of component treeReact Zero-UI:
const [, setTheme] = useUI("theme", "light");
// No re-renders, just flips data-theme="dark" on <body>Not really! If you know React hooks and Tailwind CSS, you already know 95% of what you need:
- Replace
useStatewithuseUI - Replace conditional classes with Tailwind variants
- Everything else works the same
Benchmarks (10,000 DOM nodes):
- React state changes: ~50ms
- Zero-UI state changes: ~5ms
- Result: 10× faster updates
The more complex your UI, the bigger the performance gain.
Zero-UI core: ~350 bytes in production (10x smaller than a single svg icon)
Compare that to:
- Redux: ~5KB
- SVG Icon: ~4KB So about 10x smaller than a single SVG icon
CSS variants are only generated for the states you actually use. If you use 3 theme values, you get CSS for 3 variants—not hundreds.
Here’s a tighter, sharper version with your key points, a nod to Prepack’s failure, and a forward-looking note about Turbopack:
Zero-UI uses a custom Babel-based resolver that only analyzes top-level const values in the same file. Imported variables are not supported, even if re-assigned to a local const.
Why? Because resolving cross-file imports requires a full module graph, accounting for:
- ESM vs CJS interop
- TypeScript vs JavaScript
- Re-exports, namespace imports, aliased paths, dynamic values
- Recursive constant folding across files
This problem is deceptively deep — even Facebook's Prepack abandoned the attempt after years of effort.
Until a future plugin system for Turbopack emerges, we've chosen the simpler, safer route:
Only local const string literals are supported.
We may ship a resolver plugin for Turbopack once it's open to third-party hooks.
Want it even shorter or more opinionated?
Absolutely! Zero-UI is designed for UI state only. Use it alongside:
- Redux/Zustand for business logic
- React Query for server state
- Regular
useStatefor component-specific data
// Great combination
const [data, setData] = useState(null); // Component state
const { user } = useQuery("user"); // Server state
const [, setTheme] = useUI("theme", "light"); // UI stateYes! Zero-UI is designed with SSR in mind:
- No hydration mismatches
- Perfect FOUC prevention
- Works with Next.js App Router
- Experimental server component support see experimental
Zero-UI state is DOM-based, so it doesn't persist automatically. For persistence you handle it the same as you would with regular React state:
// Save to localStorage
const [, setTheme] = useUI("theme", "light");
const persistentSetTheme = (value) => {
setTheme(value);
localStorage.setItem("theme", value);
};
// Load on mount
useEffect(() => {
const saved = localStorage.getItem("theme");
if (saved) setTheme(saved);
}, []);For the best experience, yes. Zero-UI generates Tailwind variants automatically.
and tailwind variants are generated by tailwindCSS.
[data-theme="dark"] {
background: black;
}Yes! Pass the CssVar flag:
import { useUI, CssVar } from "@react-zero-ui/core";
const [, setColor] = useUI("primary", "#blue", CssVar);
// Result: <body style="--primary: #blue">Very easy for UI state:
// Before
const [theme, setTheme] = useState("light");
// After
const [, setTheme] = useUI("theme", "light");
// Note: Don't use the first return value for logicIf context is used for UI state, it's even easier! Just remove the provider:
// Before: Need provider, useContext, prop drilling
<ThemeProvider>
<App />
</ThemeProvider>;
// After: State works everywhere automatically
function App() {
const [, setTheme] = useUI("theme", "light");
// Theme accessible anywhere via CSS classes
}No! Migrate incrementally:
- Start with global UI state (theme, modals)
- Move component-specific UI state
- Leave business logic in existing solutions
It allows interactivity in server components without 'use client' see experimental:
// This is a SERVER COMPONENT!
import { zeroSSR } from "@react-zero-ui/core/experimental";
function ServerThemeToggle() {
return <button {...zeroSSR.onClick("theme", ["light", "dark"])}>Toggle Theme</button>;
}Only ~300 bytes of runtime for unlimited server component interactivity.
It's experimental but used in production by early adopters. The API may change in minor versions, but we'll provide migration guides.
I would not recommend using it in production until the API is stable. Because the API is still in development and the API may change in minor versions, but we'll provide migration guides.
Check these in order:
-
PostCSS plugin configured? (Next.js)
// postcss.config.js module.exports = { plugins: { "@react-zero-ui/core/postcss": {}, // Before Tailwind! tailwindcss: {}, }, };
-
Tailwind V4 Configured and imported?
@import "tailwindcss";
Each useScopedUI can only attach to one element:
// Wrong
const [, setState] = useScopedUI('state', 'default');
<div ref={setState.ref} />
<div ref={setState.ref} /> // Error!
// Right
const [, setState1] = useScopedUI('state-1', 'default');
const [, setState2] = useScopedUI('state-2', 'default');
<div ref={setState1.ref} />
<div ref={setState2.ref} />Perfect for:
- Theme switching
- Modal/drawer states
- Navigation states
- UI toggles and animations
- Any visual state that doesn't affect business logic
Not ideal for:
- Form data
- API responses
- Complex business logic
- State that needs to trigger side effects
Global (useUI) for:
- App-wide state (theme, language)
- State that affects multiple components
- State you want accessible everywhere
Scoped (useScopedUI) for:
- Component-specific state
- State that doesn't affect other components
- Better performance for isolated changes
- Enhanced TypeScript support
- More framework integrations (Vue, Svelte)
- Better DevTools integration
- Performance monitoring tools
- Vote on feature requests in GitHub Discussions
- Report bugs and use cases
- Share your usage patterns
- Contribute code or documentation
- Documentation: Check the guides first
- Discussions: GitHub Discussions for questions
- Issues: GitHub Issues for bugs
- Check existing issues first
- Create a minimal reproduction
- Include your configuration (postcss.config.js, etc.)
- Include browser and framework versions
Absolutely! We welcome:
- Documentation improvements
- Bug fixes
- Feature implementations
- Examples and demos
See our Contributing Guide to get started.
Ask in Discussions | Read the Docs | Try the Demo
The community is here to help!