Laravel + Livewire or a React SPA: choose by where the state lives
Livewire keeps application state on the server: interactions are round-trips, Blade re-renders fragments, Eloquent stays the single source of truth. React holds state in the browser and talks to an API. Business apps made of forms and tables want the first; dense, instant, offline-capable interfaces want the second.
I have shipped both, and the framework question turned out to be the wrong starting point. The right question is: where does the truth of the current screen live?
When does Livewire beat a React SPA?#
When the product is a form-and-table application that Laravel already models: admin panels, customer portals, internal tools. Concretely:
- Validation lives in Form Requests once. There is no second JavaScript implementation of the same rules to drift out of sync.
- Authorization uses Laravel Policies. There is no API layer to forget protecting, because there is no API layer.
- Pages are server-rendered by default, so search engines see content without an SSR pipeline.
- One deploy, one log stream, one error tracker.
The price: every interaction costs a network round-trip. That is fine for "save this form" and wrong for "drag this slider while thirty rows re-sort". The day a UI needs instant feedback on dense local state, Livewire starts fighting you: wire:model.live debounce tuning, loading placeholders that flash, and a request rate that multiplies with every wired input.
When does the SPA win?#
React (with Next.js for anything URL-visible) earns its toolchain when the interface is the product: editors, dashboards with heavy local interactivity, anything that must work offline, screens where optimistic updates matter more than request counts. State lives where the interaction happens, so the UI never waits on the network to feel responsive.
The costs are the mirror image: an API contract to version, a second authentication boundary to defend, SEO to engineer deliberately, and two deploys where there was one. Those costs are worth paying for the right product and wasteful for the wrong one.
Side by side#
| Dimension | Livewire 3 | React SPA |
|---|---|---|
| State location | Server (session, database) | Browser + API |
| Interaction latency | One network round-trip | Instant, local |
| Backend | Eloquent, Blade, one app | Separate API contract |
| SEO | Server-rendered by default | Needs SSR (Next.js) |
| Team baseline | PHP, Blade | TypeScript, build tooling |
| Offline use | No | Feasible |
| Ecosystem | Laravel packages | npm, larger by an order of magnitude |
What decided each case in practice#
An operations portal with around forty screens (forms, tables, approval flows, exports) runs on Livewire and never wanted to be a SPA: every screen maps to server state, so the whole thing is one Laravel app.
The Röstwerk Mini App storefront is React precisely because a shop cart inside a Telegram webview needs instant local feedback on subtotal, quantity, and validation. Rendering that on a server per tap would be noticeable and worse.
This site is Next.js, because a blog with a command palette, theme switching, and client-side reading progress is exactly the kind of interface React was built for. What that choice bought down to the Lighthouse numbers is written up separately: the performance pass in detail.
Livewire re-runs the component lifecycle on every update. A search input wired to fire per keystroke is a database hammer: debounce deliberately, keep expensive renders out of the hot path, and watch the request rate in dev tools before your users teach it to you through the load average.
The migration nobody budgeted for#
Choosing wrong is fixable. The expensive part is not porting components; it is redrawing the state boundary. Moving server-owned state into a client store means inventing the API, the optimistic-update rules, and the invalidation logic you previously got for free. If you expect that migration, plan the escape hatch before you need it: incrementally, per screen, with the old path intact until the new one proves itself.
There is no stack that wins on both axes. Decide once, in writing, where state lives for each screen you plan. The framework choice falls out of that sentence.