Inertia and a BAP both let a Laravel application keep its routes, its controllers or classes, its auth and its models, and put React in front. They differ in where the page is made.
Inertia keeps the page in Laravel. A controller loads the data and hands it to a React component as props; the browser renders it, and server-side rendering is an optional second process. React is a view layer.
A BAP — Backend-Answered Pages — puts a
renderer in front. Pages are React Server Components; one that needs data
calls into Laravel with rpc(), and Laravel answers that call, the session’s
guards and the server actions. React owns the page.
At a glance
| Inertia | BAP | |
|---|---|---|
| Maturity | Years in production, a large community | Pre-1.0; the contract still moves |
| Who decides the data | The controller, for the whole page | Each component, for itself |
| Slow data | The page waits for the slowest query | Each part streams in under its own <Suspense> |
| Pages that are the same for everyone | Rendered on every request | Stored at build time, served without PHP |
| JavaScript a page ships | All of it: every page is a client component | Only the interactive parts |
| Types between PHP and TypeScript | Written by hand, or generated by a separate tool | Generated from the PHP signatures on every build |
| Processes in production | Laravel, plus an SSR server if you use one | Laravel and the renderer, always |
| Where a request goes first | Laravel | The renderer, which forwards what it does not own |
| What you learn | Laravel and React | Laravel, React Server Components, and where code runs |
Choose Inertia when
- You want the mature, well-trodden option and a large community to ask.
- Your pages are mostly behind a login and not worth storing at build time.
- Your team knows Laravel deeply and wants React only as the view.
- You would rather not run a second process in production.
Choose a BAP when
- A slow part of a page should not hold back the rest: dashboards, feeds, pages that read several services.
- Some pages are the same for everyone — marketing, docs, pricing — and should be served from disk or a CDN with nothing ships but HTML.
- You want the contract between PHP and TypeScript generated, so removing a field in PHP fails the typecheck where it was used.
- You want to ship less JavaScript: server components send none.
What the BAP asks of you
- Know where code runs. Server components run in the renderer, client components in the browser, your functions in Laravel. Most confusion in a BAP is a question about which of the three a line is in.
- Accept a younger contract. Every adapter is checked by a conformance suite, but it is pre-1.0, and a mismatch at the boundary is still possible.
- Run the renderer. It is a Node or Bun process beside PHP; deployment is two processes.
Moving between them
Nothing in Laravel is Inertia-specific except the controllers that return
Inertia::render. A BAP reaches the same models and policies through
app/Rsc classes, so a move is page by page: a React tree’s page wins its
url, and every url it does not have is still Laravel’s. See
Coming from Inertia.