React Zero-UI FAQ
Answers about preventing React re-renders, replacing UI context state, SSR defaults, scoped UI, and Tailwind variants.
General Questions
What exactly is React 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.
How is this different from regular React state?
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>Do I need to learn anything new?
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
Performance Questions
How much faster is it really?
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.
Does it increase my bundle size?
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
What about CSS file size?
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.
Technical Questions
Why can't I use imported variables in the state key?
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.
Can I use it with existing state management?
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 stateDoes it work with SSR/Next.js?
Yes! 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
Can I persist state across page reloads?
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);
}, []);Styling Questions
Do I have to use Tailwind?
For the best experience, yes. Zero-UI generates Tailwind variants automatically.
Tailwind variants are generated by Tailwind CSS.
[data-theme="dark"] {
background: black;
}Can I use CSS variables?
Yes! Pass the CssVar flag:
import { useUI, CssVar } from "@react-zero-ui/core";
const [, setColor] = useUI("primary", "#blue", CssVar);
// Result: <body style="--primary: #blue">Migration Questions
How hard is it to migrate from useState?
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 logicWhat about Context API?
If 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
}Should I migrate everything at once?
No! Migrate incrementally:
- Start with global UI state (theme, modals)
- Move component-specific UI state
- Leave business logic in existing solutions
Experimental Features
What's the experimental SSR runtime?
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.
Is the experimental API stable?
It's experimental but used in production by early adopters. The API may change in minor versions, but we'll provide migration guides.
Should I use it in production?
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.
Troubleshooting
My Tailwind variants aren't working
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";
I get "Multiple ref attachments" error
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} />Best Practices
When should I use Zero-UI?
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
Should I use global or scoped state?
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
Future & Roadmap
What's coming next?
- Enhanced TypeScript support
- More framework integrations (Vue, Svelte)
- Better DevTools integration
- Performance monitoring tools
How can I influence the roadmap?
- Vote on feature requests in GitHub Discussions
- Report bugs and use cases
- Share your usage patterns
- Contribute code or documentation
Getting Help
Where can I ask questions?
- Documentation: Check the guides first
- Discussions: GitHub Discussions for questions
- Issues: GitHub Issues for bugs
How do I report a bug?
- Check existing issues first
- Create a minimal reproduction
- Include your configuration (postcss.config.js, etc.)
- Include browser and framework versions
Can I contribute?
Absolutely! We welcome:
- Documentation improvements
- Bug fixes
- Feature implementations
- Examples and demos
See our Contributing Guide to get started.
Still have questions?
Ask in Discussions | Read the Docs | Try the Demo
The community is here to help!