Livewire vs Inertia.js en Laravel — Cuál elegir para tu proyecto
Si quieres construir una aplicación Laravel moderna con interactividad sin escribir una SPA desde cero, tienes dos opciones principales: Livewire y Inertia.js. Ambas son excelentes, pero tienen filosofías muy diferentes. La elección correcta depende de tu equipo, tu proyecto y lo que valoras más.
¿Qué es Livewire?
Livewire es un framework de componentes full-stack para Laravel. Todo el código vive en el servidor (PHP), y Livewire se encarga de sincronizar el estado entre el servidor y el navegador usando AJAX invisible para el desarrollador.
// app/Livewire/SearchPosts.php
<?php
namespace App\Livewire;
use App\Models\Post;
use Livewire\Component;
use Livewire\WithPagination;
class SearchPosts extends Component
{
use WithPagination;
public string $search = '';
public string $category = '';
// Cuando $search cambia, se re-renderiza automáticamente
public function updatedSearch(): void
{
$this->resetPage();
}
public function render()
{
$posts = Post::query()
->when($this->search, fn($q) => $q->where('title', 'like', "%{$this->search}%"))
->when($this->category, fn($q) => $q->where('category', $this->category))
->with('user')
->paginate(10);
return view('livewire.search-posts', compact('posts'));
}
}
{{-- resources/views/livewire/search-posts.blade.php --}}
<div>
<input
type="text"
wire:model.live="search"
placeholder="Buscar posts..."
class="border rounded px-3 py-2"
>
<select wire:model.live="category">
<option value="">Todas las categorías</option>
<option value="laravel">Laravel</option>
<option value="php">PHP</option>
</select>
<div class="posts-grid">
@foreach ($posts as $post)
<article>
<h2>{{ $post->title }}</h2>
<p>{{ $post->user->name }}</p>
</article>
@endforeach
</div>
{{ $posts->links() }}
</div>
{{-- resources/views/posts/index.blade.php --}}
@livewire('search-posts')
Todo el código es PHP/Blade. No hay JavaScript que escribir.
¿Qué es Inertia.js?
Inertia.js es un protocolo que conecta un backend Laravel con un frontend SPA (React, Vue o Svelte) sin necesidad de construir una API REST separada. El backend sigue manejando rutas y autenticación, pero en lugar de devolver HTML, devuelve datos que el frontend renderiza.
// app/Http/Controllers/PostController.php
public function index(Request $request)
{
$posts = Post::with('user')
->when($request->search, fn($q) => $q->where('title', 'like', "%{$request->search}%"))
->paginate(10);
// En vez de return view('posts.index', [...])
// Devuelves un componente de Vue/React con datos
return Inertia::render('Posts/Index', [
'posts' => PostResource::collection($posts),
'search' => $request->search ?? '',
]);
}
<!-- resources/js/Pages/Posts/Index.vue -->
<script setup>
import { ref } from 'vue'
import { router } from '@inertiajs/vue3'
import { debounce } from 'lodash'
const props = defineProps(['posts', 'search'])
const search = ref(props.search)
const performSearch = debounce((value) => {
router.get(route('posts.index'), { search: value }, {
preserveState: true,
replace: true,
})
}, 300)
</script>
<template>
<div>
<input
v-model="search"
@input="performSearch(search)"
placeholder="Buscar posts..."
>
<article v-for="post in posts.data" :key="post.id">
<h2>{{ post.title }}</h2>
<p>{{ post.author.name }}</p>
</article>
<!-- Paginación -->
<div>
<a v-for="link in posts.links" :key="link.label"
:href="link.url"
v-html="link.label">
</a>
</div>
</div>
</template>
Comparativa técnica
Cómo funciona la interactividad
Livewire: Cuando el usuario escribe en el input, Livewire hace una petición AJAX al servidor con el nuevo estado, el servidor re-ejecuta el componente PHP, devuelve el HTML actualizado, y Livewire actualiza el DOM con morphdom (sin recargar la página completa).
Inertia: Cuando el usuario navega, Inertia hace una petición XHR al servidor, el servidor devuelve un JSON con los props del nuevo componente, e Inertia pasa esos props al componente Vue/React sin recargar la página.
Cantidad de JavaScript
Livewire: Cero JavaScript que escribir para la lógica.
Alpine.js opcional para pequeñas interacciones de UI.
Inertia: Vue/React completo. Escribes componentes JavaScript
con toda la lógica del frontend.
Curva de aprendizaje
Livewire: Si sabes PHP y Blade, empiezas a construir en minutos. La curva es mínima para desarrolladores backend.
Inertia: Requiere conocer bien Vue o React. Necesitas entender el ecosistema JavaScript (Vite, npm, composables/hooks, estado reactivo).
Livewire 3 y Volt
Livewire 3 introdujo Volt, que permite escribir componentes en un solo archivo mezclando PHP y Blade:
<?php
// resources/views/livewire/counter.blade.php
use Livewire\Volt\Component;
new class extends Component {
public int $count = 0;
public function increment(): void
{
$this->count++;
}
} ?>
<div>
<h1>{{ $count }}</h1>
<button wire:click="increment">+1</button>
</div>
Una sintaxis muy limpia, similar a los Single File Components de Vue pero en PHP.
Rendimiento
Livewire:
- Cada interacción = petición al servidor
- Bueno para interacciones ocasionales (búsquedas, formularios)
- Puede ser lento con muchas interacciones rápidas (typing en tiempo real)
Inertia:
- Las transiciones de página no recargan el HTML completo
- El estado reactivo ocurre en el cliente (sin petición al servidor)
- Mejor para apps con muchas interacciones en el cliente
¿Cuándo elegir Livewire?
Livewire es la mejor opción cuando:
- Tu equipo es principalmente backend (PHP)
- La app es CRUD con algo de interactividad (búsqueda, filtros, formularios dinámicos)
- Quieres desplegar rápido sin aprender un framework JS
- El SEO es importante (renderiza en el servidor por defecto)
- Tienes un blog, panel de administración, dashboard interno
// Casos de uso perfectos para Livewire:
// - Formularios con validación en tiempo real
// - Tablas con búsqueda y filtros
// - Carritos de compra simples
// - Paneles de administración
// - Cualquier cosa donde el DOM no cambia radicalmente
¿Cuándo elegir Inertia?
Inertia es la mejor opción cuando:
- Tu equipo conoce bien Vue o React
- La app tiene interacciones ricas de UI (drag & drop, animaciones complejas, canvas)
- Quieres compartir componentes con una app móvil
- Necesitas un ecosistema frontend maduro (librerías UI, testing con Vitest)
- Construyes algo similar a una SPA pero sin querer mantener una API separada
// Casos perfectos para Inertia:
// - Apps estilo Notion, Trello, Figma (muchas interacciones)
// - Editores de texto enriquecido
// - Apps con drag & drop
// - Cuando ya tienes diseñadores que saben React/Vue
El factor equipo
Esta es quizás la consideración más importante:
- Solo tú o equipo PHP: Livewire, sin duda. No tiene sentido aprender React/Vue si puedes construir todo en PHP.
- Equipo mixto o con experiencia frontend: Inertia. Los desarrolladores frontend estarán mucho más cómodos.
- Contratando: Inertia tiene más candidatos (hay más devs Vue/React que Livewire).
Pueden coexistir
No tienes que elegir uno u otro para toda la aplicación. Puedes usar Inertia para las páginas principales y Livewire para componentes específicos, o viceversa. Aunque esto añade complejidad, es válido en proyectos grandes.
Conclusión
Si eres principalmente desarrollador backend y quieres agregar interactividad sin aprender JavaScript profundamente, Livewire es la respuesta. Si tu equipo tiene experiencia en Vue o React y quieres construir una experiencia de usuario más rica, Inertia conecta perfectamente ese conocimiento con Laravel. Ambas son elecciones profesionales válidas y productivas.