React
This guide takes a fresh Vite + React project to a fully offline-resilient, single-bootstrap, realtime-synced app — using whichever state manager you already work with.
- An existing Vite + React project.
- (Optional)A backend you can subscribe to — Supabase, or any server that can speak Socket.io, SSE, or raw WebSocket.
- Node 18+.
Install the core package
Install the React integration
FluxProvider, HydrationGate, FluxErrorBoundary, fluxVitePlugin (the Vite plugin that injects your service worker at build time), and the useFlux() / useFluxTime() hooks — the same hooks flux-next ships, minus anything Next.js-specific like RSC handling.Choose your realtime adapter
createPollingAdapter() still gets you full IDB caching, the offline queue, and the SW layer — you're only trading live push updates for a polling interval. Swap in a real adapter later with no changes to your register() calls. If you have no backend at all — static marketing pages or fully hardcoded data — choose the **No realtime backend** option above and use createNoopAdapter() instead. It disables the realtime layer entirely while keeping the rest of the stack.
Define your precache route manifest
Configure the Vite plugin
withFlux() in Next.js, this plugin has no server-rendered build manifest to read for dynamic-route chunk warming — Vite emits a client-only dist/.vite/manifest.json, and fluxVitePlugin reads it in closeBundle to bake chunk hashes into the generated service worker.Add your manifest.json
public/manifest.json. Flux's service worker reads it during installation to configure the PWA shell. This step is required for every app — static sites included — because the SW uses the manifest icons and theme colors for the offline splash.Define your types (TypeScript only)
Create your state store
store on register() needs a setState(data) method with this exact signature, because dispatchToStore calls it directly on every IDB cold-boot read, every bootstrap dispatch, and every realtime event.Zustand — native, no adapter needed
Redux Toolkit
Jotai
createStore() since Flux dispatches outside of the React render tree:Stunk
Create the Flux engine singleton
Pick the tab matching the adapter you installed in Step 3. Vite modules execute once per page load, functioning naturally as singletons without Fast Refresh engine guards.
Wrap your app
The hydrate → bootstrap sequence
Your bootstrap API route (Node / Express)
Dynamic detail pages that work offline (optional)
Your offline fallback page
precacheRoutes and offlineShell in your fluxVitePlugin() config (Step 5).Offline-ready static images (optional)
flux.register(), use CachedImg to store them in Flux's image IndexedDB cache.If you have no data to sync — a marketing page, a static docs page, anything with no register() calls — you don't need Steps 8 through 14 at all. All you need is:
Add every route you want available offline to precacheRoutes, plus your offline shell page from Step 14. The service worker generated by fluxVitePlugin() precaches these at build time regardless of whether createFlux() is called.
Every adapter shown here — Supabase, Socket.io, SSE, WebSocket, polling — and every state manager — Zustand, Redux, Jotai, Stunk — are interchangeable independently of each other and of the framework. Nothing in @tsworldtech/flux's core engine knows whether it's running inside Next.js or a plain Vite build.