Inertia.js Explained: The Modern Monolith with Laravel + React
In the modern web development landscape, we often face a difficult dichotomy: Build traditional Server-side Rendering (SSR) applications with frameworks like Laravel/Rails, or build completely detached Single Page Applications (SPAs) using Vue/React that communicate via REST/GraphQL APIs.
The latter option offers a smooth user experience but comes at a high cost: complexity in state management, routing, authentication, and the burden of maintaining two separate projects (frontend and backend). Inertia.js was created to solve exactly this problem.
Inertia is not a framework meant to replace Vue or React. It is a "glue library" that connects a server-side framework (like Laravel) with a client-side framework (like React).
Instead of returning standard HTML, the server returns a JSON object known as the Inertia Page Object. The client-side adapter receives this JSON and swaps the components without reloading the entire page.
The Core Philosophy:
You write Controllers, Routing, Middleware, and Auth exactly as you would in traditional web development. However, your View layer consists of modern React/Vue components instead of Blade/Erb templates.
- ✔ No API Required: You don't need RESTful endpoints, serializers, or complex DTOs for your internal UI.
-
✔
Server-side Routing: You use Laravel's
routes/web.phpfile. No need to redefine routes on the client side (like with React Router). - ✔ Simple Authentication: Uses Laravel's default session cookies. No need to handle JWTs, token refreshing, or localStorage security concerns.
Let's look at how data is passed from Laravel to a React Component naturally:
Laravel Controller (UserController.php):
use Inertia\Inertia;
public function show(User $user)
{
return Inertia::render('Users/Show', [
'user' => [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'can' => [
'edit' => auth()->user()->can('edit', $user)
]
]
]);
}
React Component (Users/Show.jsx):
export default function Show({ user }) {
return (
<div>
<h1>{user.name}</h1>
<p>Email: {user.email}</p>
{user.can.edit && (
<Link href={`/users/${user.id}/edit`}>Edit User</Link>
)}
</div>
);
}
As you can see, data is passed directly into the component as props. Everything works synchronously and is easy to understand.
Inertia doesn't just stop at rendering data; it provides a full suite of tools for a complete SPA:
Automatically share common data across all requests (like the logged-in user) without manually passing props.
Create SPA links that intercept page reloads, providing an instant, smooth feel.
The useForm hook makes handling form submissions, validation errors, and loading states incredibly simple.
Automatically remembers scroll positions when navigating back and forth (history navigation).
While excellent, Inertia is not a silver bullet for every problem. You should consider other solutions if:
- You need to build a native Mobile App that needs to share the same backend. (In this case, an API is mandatory).
- The Backend and Frontend are developed by two organizationally separate teams.
- You only need a simple landing page with minimal interactivity (pure Blade would be faster).
Inertia.js has changed the game for Full-stack developers. It allows us to leverage the power of React/Vue without losing the convenience and rapid development speed of Laravel.
If you are looking for a solution to modernize your monolith application, Inertia is the answer. Start installing and experiencing it today!
