Índice de contenido
- ¿Qué nos ofrece Livewire?
- Reactividad sin complicaciones
- Casos de uso: SEO y Dashboards
- Un ecosistema en constante evolución
- Qué permite Livewire
- ¿Por qué elegir Livewire para tu proyecto Laravel?
- Elementos esenciales de un proyecto Livewire
- Dependencias clave: Volt, Flux y más
- Laravel Volt
- Laravel Flux UI
- Data-binding, props y eventos (wire:model, actions)
- Que nos trae un Proyecto en Laravel Livewire
- ¿Por qué el emoji ⚡?
- Componentes de un solo archivo (Livewire Volt)
- Blade, Componentes de Blade, Layouts y Flux
- Ruteo, vistas y página única (sin controlador tradicional)
- Carga de archivos, validación en tiempo real y lazy loading
- Analizando un proyecto en Livewire
- LO que Más me GUSTA de LARAVEL (LIVEWIRE) wire:click
- Los eventos de Livewire la clave
- Lo segundo mejor de Laravel Livewire, sus componentes REALES
- Livewire: Componentes Reales, No Solo Vistas
- Comparación con Inertia.js
- ¿Qué Implica Esto?
- Cosas que NO me gustan de Laravel Livewire... Su "Complejidad"
- Los "problemas" de Livewire: Complejidad y Abstracto
- ¿Más Opciones? Sí. ¿Más Código? También
- Comunicación Inversa: Padre a Hijo
- ¿Demasiadas Opciones?
- Buenas prácticas que debes seguir
- Performance y carga diferida
- SEO, accesibilidad y experiencia de usuario
- Testing, mantenimiento y escalabilidad
- Jetstream el legado
- Que permiten los equipos de Laravel Livewire
- Gestión de Tokens de autenticación
- Jetstream, Livewire y Tailwins.CSS
- FAQs: Preguntas frecuentes sobre proyectos Livewire
Antes de comenzar a desarrollar nuestra aplicación en Livewire, una vez creado el proyecto en Laravel Livewire, quiero hacer una pequeña pausa para comentarte qué es lo que tenemos en un proyecto con este framework.
En pocas palabras, podemos decir que Livewire son componentes de Laravel “vitaminizados”. Es decir, con estos componentes podemos hacer múltiples operaciones que normalmente requerirían mucho más código o configuraciones adicionales.
Cuando comienzas un proyecto con Laravel Livewire, especialmente desde la versión 12 en adelante, rápidamente descubres que no estás trabajando con “Laravel tradicional”, sino con algo que —como me pasó a mí la primera vez— se siente como componentes de Laravel vitaminizados. En este artículo te explico, desde la práctica, cuáles son las características reales de un proyecto Livewire moderno, cómo está construido, qué incluye, qué cambia respecto a versiones anteriores y cómo sacarle todo el jugo.
Vamos a hablar sobre los aspectos más importantes que tenemos al momento de crear un proyecto en Laravel Livewire a partir de la versión 12 de Laravel, que como comentamos antes, a diferencia de versiones anteriores, ya no trae incluidas las funcionalidades que tenemos en versiones anteriores con Jetstream.
¿Qué nos ofrece Livewire?
Crear aplicaciones modernas hoy en día es un reto. No solo debemos dominar el Backend (donde Laravel es el rey indiscutible), sino también la capa de presentación o Frontend. Tradicionalmente, esto implicaba usar frameworks como Vue o React, lo que nos obligaba a separar nuestro desarrollo en dos mundos distintos, aumentando la complejidad y el mantenimiento.
Aquí es donde entra Livewire: un framework full-stack para Laravel que nos otorga las bondades de la reactividad (muy similares a lo que ofrece Vue) pero manteniéndonos integrados al 100% en el ecosistema de Laravel. Es, literalmente, lo mejor de dos mundos.
Livewire es un marco completo para Laravel que simplifica la creación de interfaces dinámicas, sin dejar la comodidad de Laravel; en pocas palabras nos permite usar esquemas similares a los de Vue y React directamente en Laravel.
Podemos trabajar con esquemas similares a los de Laravel y Vue, pero de una manera más directa y simple; el desarrollo de Laravel está fuertemente ligado al uso de componentes; los mismos componentes de Laravel pero con agregados importante de Laravel Livewire lo que permite escalar enormemente el uso de componentes:
- Vincular mediante el archivo de rutas.
- Comunicación sencilla basada en acciones, eventos y funciones entre el cliente y el servidor.
- Agrega funcionalidades como paginación, carga de archivos, query string entre otras.
En definitiva, con Livewire, podemos hacer lo mismo que hacemos con Laravel y sus controladores, pero de una manera más sencilla en la cual podemos usar los componentes y reutilizar piezas de código que nos ofrece Livewire para hacer una comunicación muy sencilla entre el servidor con el cliente.
Reactividad sin complicaciones
Para mí, lo mejor de Livewire es la potencia de sus eventos. En un desarrollo tradicional o con APIs, realizar una acción como "clonar un post" requeriría:
- Crear una ruta.
- Implementar una llamada con Axios.
- Manejar la respuesta en el cliente.
Con Livewire, esto se reduce a un atributo wire:click (o similar) que llama directamente a un método del servidor. Es magia pura y simplifica el flujo de trabajo de una manera increíble.
Aparte de que, dependiendo como decidas instalar a Laravel Livewire, puedes habilitar opciones que ya vienen de gratis como:
- Sistema de autenticación con registro, recuperación de credenciales.
- Vista de perfil con carga de usuario.
- Manejo de equipos mediante equipos.
En definitiva, Livewire no es un framework, lo puedes ver como un paquete más que agrega funcionalidades extras a algunos elementos de Laravel que lo convierten en un scaffolding o esqueleto para nuestras aplicaciones.
Casos de uso: SEO y Dashboards
Livewire es extremadamente versátil. En mi propio blog, por ejemplo, utilizo una combinación estratégica:
- Administración (Dashboard): Uso Livewire para aprovechar la velocidad de desarrollo y la reactividad en formularios y tablas.
- Parte pública (Blog): Empleo Laravel directamente, ya que al renderizarse en el servidor, el contenido es fácilmente indexable por Google, a diferencia de algunas implementaciones pesadas en JS o usando Livewire.
Un ecosistema en constante evolución
Livewire y Laravel cambian rápido. Livewire lanza versiones mayores cada cierto tiempo y Laravel lo hace anualmente. En este curso, no solo aprenderemos la teoría, sino la implementación moderna:
- Componentes en un solo archivo: Veremos cómo Livewire está migrando hacia una estructura similar a los Single File Components de Vue, donde la lógica y el HTML pueden convivir para mejorar la velocidad de desarrollo.
- Integración con Alpine.js: Para aquellas interacciones que no necesitan viajar al servidor, Livewire se apoya en Alpine.js, un framework de JS ligero que también cubriremos.
Qué permite Livewire
Con los componentes de Livewire podemos:
- Realizar ruteo de vistas: en vez de que un controlador devuelva una vista, podemos hacerlo mediante un componente.
- Usar propiedades dinámicas, similares a los v-model de Vue, para enlazar datos entre el frontend y el backend de forma reactiva.
- Trabajar con query strings para mantener información en la URL y sincronizarla con el estado del componente.
- Manejar la carga de archivos de manera sencilla.
- Y muchas otras operaciones más que iremos viendo en la práctica.
No quiero adelantar demasiado, porque algunas funciones son más técnicas y es mejor explorarlas directamente mientras construimos nuestra aplicación.
Lo importante es quedarte con la idea: Livewire nos da componentes de Laravel mejorados, con muchas funcionalidades listas para usar, lo que nos permite desarrollar aplicaciones dinámicas sin salir del ecosistema de Laravel.
¿Por qué elegir Livewire para tu proyecto Laravel?
Livewire se ha posicionado como una solución intermedia perfecta entre Blade tradicional y frameworks SPA como Vue o React. Es ideal para quienes quieren interfaces reactivas sin tener que levantar toda una infraestructura de JavaScript moderno.
En mis primeros proyectos con Livewire, una de las cosas que más me sorprendió fue poder hacer acciones instantáneas con wire:model, wire:click, o incluso manejar Query Strings sin escribir una sola línea de JS. Literalmente, conectas una propiedad a la vista y el estado fluye.
Ventajas principales a destacar:
- Eliminación del JS complejo para la mayoría de interacciones.
- Integración 100% nativa con Blade.
- Componentes reutilizables y anidados.
- Carga diferida, validación instantánea, subida de archivos.
- Ideal para paneles, dashboards, CRUDs y herramientas internas.
Elementos esenciales de un proyecto Livewire
Estructura de carpetas y componentes
Un proyecto Livewire en Laravel 12 se basa en la idea de que cada parte de tu interfaz es un componente. Esto incluye formularios, dashboards, sidebar, perfiles y cualquier elemento que necesite lógica y vista.
En mis primeros pasos noté que, a diferencia de versiones anteriores, la dependencia directa de Livewire ya no aparece en composer.json: ahora llega a través de paquetes como Volt y Flux, lo cual cambia la arquitectura del proyecto.
Si revisas la estructura de un proyecto Livewire recién instalado, notarás:
- /app/Livewire → donde viven los componentes
- /resources/views/livewire → vistas blade de cada componente
- /resources/views/components → componentes Blade auxiliares
- /routes/web.php → rutas que pueden apuntar directamente a componentes Livewire
Es común ver rutas como:
Route::get('/dashboard', \App\Livewire\Dashboard::class);Dependencias clave: Volt, Flux y más
En Livewire 12+, el ecosistema viene reforzado con:
Volt
Volt permite construir lógica y vista en un solo archivo, algo que se siente casi como Svelte o Vue Single File Components, pero directamente en Blade.
Un ejemplo típico:
<?php
use function Livewire\Volt\{state};
state(['count' => 0]);
$increment = fn () => $this->count++;
?>
<div>
<h1>{{ $count }}</h1>
<button wire:click="increment">+</button>
</div>Volt no es de mis tecnologías favoritas, ya que, no me gusta que mezclemos lógica con presentación y en Livewire 4 inclusive vamos a tener una tercera forma de poder crear componentes en Livewire, aun así, es una estructura completamente válida.
Laravel Volt
En proyectos recientemente de Laravel Livewire, a partir de la versión 12 de Laravel, al crear un proyecto en Laravel Livewire incluye otras tecnologías como:
Volt:
https://livewire.laravel.com/docs/volt
Con la cual, podemos crear tanto la lógica como la vista (blade) en un solo archivo:
<?php
use function Livewire\Volt\{state};
state(['count' => 0]);
$increment = fn () => $this->count++;
?>
<div>
<h1>{{ $count }}</h1>
<button wire:click="increment">+</button>
</div>Laravel Flux UI
También veremos que los componentes auxiliares que empleamos ahora no son los mismos que antes, ahora empleamos flux.
Flux, que no es más que una librería de componentes para Laravel Livewire ya listos para utilizar:
https://fluxui.dev/
<flux:input
wire:model="email"
:label="__('Email address')"
type="email"
required
autocomplete="email"
placeholder="email@example.com"
/>Que puedes exponer para personalizar:
$ php artisan flux:publishTambién vemos una estructura más compleja como que en el composer.json no tenemos la dependencia a Livewire, si no, a los paquetes anteriores que importan Livewire como una dependencia.
Flux es una librería de componentes UI preconstruidos que Livewire integra para acelerar el desarrollo, realmente tiene componentes muy buenos, es de tipo freemium, lo que significa que, tiene componentes gratis y de pago.
Componentes como:
<flux:input>
<flux:navlist>
<flux:dropdown>
<flux:menu>
<flux:profile>Por ejemplo:
<flux:input
wire:model="email"
label="Email"
type="email"
required
/>Estos son componentes Laravel con toneladas de clases Tailwind, fáciles de extender:
$ php artisan flux:publishCon el comando anterior, puedes publicar TODOS los componentes de flux para analizarlos.
Data-binding, props y eventos (wire:model, actions)
Livewire permite que las vistas y la lógica se mantengan sincronizadas automáticamente.
Ejemplos:
- wire:model="email" mantiene el estado entre input y componente.
- wire:click="save" ejecuta métodos del backend sin recargar.
- wire:loading maneja estados de carga.
- wire:keyup.debounce.500ms optimiza eventos.
Para mi, LO MEJOR de Livewire es el wire:click.
Que nos trae un Proyecto en Laravel Livewire
En este apartado, vamos a hablar sobre los aspectos más importantes que tenemos al momento de crear un proyecto en Laravel Livewire a partir de la versión 13 de Laravel con Livewire 4, que como comentamos antes, a diferencia de versiones anteriores, ya no trae incluidas las funcionalidades que tenemos en versiones anteriores con Jetstream, aunque si incluyeron nuevamente el manejo de Teams de manera opcional.
Lo primero que vemos, es un par de enlaces para registrarse y login, en este punto, si ya no los has hecho, crea un usuario; una vez registrado o iniciar la sesión, tendrás acceso a; crea un usuario:
http://livewirestore.test/register
Y enviará a:
Si seleccionastes team: http://livewirestore.test/team-1/dashboard
Sin team: http://livewirestore.test/dashboard
Publica el archivo de configuraciones de Livewire:
$ php artisan livewire:publish --configO
$ php artisan livewire:config
Que es un archivo de configuración, en donde verás, el layout empleado:
config\livewire.php
'component_layout' => 'layouts::app',Te recomiendo que revises el archivo mencionado, veras información como indica que ya inyecta el CSS y JS de Livewire para poder emplear los atributos y peticiones (que vamos a conocer más adelante):
The view that will be used as the layout when rendering a single component as | an entire page via `Route::livewire('/post/create', 'pages::create-post')`. | In this case, the content of pages::create-post will render into $slot.Puedes crear tus layouts para otros módulos y sobrescribir en las configuraciones, aunque te recomiendo que de momento que no los crees:
$ php artisan livewire:layoutY puedes ver que, en la ruta:
- resources\views\layouts\app.blade.php
Veras el layout de la app:
<x-layouts::app.sidebar :title="$title ?? null">
<flux:main>
{{ $slot }}
</flux:main>
</x-layouts::app.sidebar>Que internamente, emplea otros componentes que estan al mismo nivel en una carpeta app:
- app
- header
- sidebar
Si por ejemplo, vez el componente de:
resources\views\pages\settings\⚡profile.blade.php
Veras varias cosas interesantes, como la composición de un único archivo (HTML y PHP en un mismo archivo), clases sin nombre, uso de atributos de PHP que es nuevo desde la versión 8:
new #[Title('Profile settings')] class extends Component {
use ProfileValidationRules;Y el pase de parámetro:
resources\views\pages\settings\⚡profile.blade.php
Title('Profile settings')resources\views\layouts\app.blade.php
<x-layouts::app.sidebar :title="$title ?? null">Antes para pasar parámetros era:
->layoutData(['title' => 'Teams'])Y lo mejor de todo, NO existe una ruta para esta página:
Route::view('/', 'welcome', [
'canRegister' => Features::enabled(Features::registration()),
])->name('home');
Route::prefix('{current_team}')
->middleware(['auth', 'verified', EnsureTeamMembership::class])
->group(function () {
Route::view('dashboard', 'dashboard')->name('dashboard');
});
Route::middleware(['auth'])->group(function () {
Route::livewire('invitations/{invitation}/accept', 'pages::teams.accept-invitation')->name('invitations.accept');
});Y puedes ver desde el dashboard, en el navbar, una opción al perfil:
- http://livewirestore.test/settings/profile
¿Por qué el emoji ⚡?
Quizás te preguntes por el rayo en el nombre del archivo. Este pequeño detalle tiene una función práctica: permite que los componentes de Livewire sean reconocibles al instante en el árbol de archivos y los resultados de búsqueda de tu editor. Al ser un carácter Unicode, funciona a la perfección en todas las plataformas: Windows, macOS, Linux, Git y tus servidores de producción.
El emoji es totalmente opcional y, si no te resulta cómodo, puedes desactivarlo por completo en tu archivo config/livewire.php:
'make_command' => [ 'emoji' => false, ],
Componentes de un solo archivo (Livewire Volt)
Otra novedad que puede chocar es la estructura de los componentes. Tradicionalmente, teníamos una clase en PHP y una vista en Blade. Ahora, con Volt, todo se puede unir en un mismo bloque:
- Lógica funcional: Arriba tenemos un bloque de PHP (a veces identificado con un emoji en el editor) donde definimos las propiedades y funciones.
- Atributos Dinámicos: Usamos atributos de PHP 8 (como #[Layout]) para pasar datos directamente al layout, como el título de la página.
- HTML: Justo debajo tenemos el código Blade.
Es una mezcla muy potente que recuerda a los componentes de Vue, pero procesada enteramente en el servidor. Al estar todo en el mismo archivo, ya no necesitamos una función render(), pues Livewire asume que el HTML de abajo es lo que debe mostrar.
Blade, Componentes de Blade, Layouts y Flux
Cómo puedes apreciar, x-layout-app, corresponde a un componente en Laravel base:
resources/views/components/layouts/app.blade.php
<x-layouts.app.sidebar :title="$title ?? null">
<flux:main>
{{ $slot }}
</flux:main>
</x-layouts.app.sidebar>Otra cosa extraña del código anterior es que, el componente que inicia con flux, los cuales, son los componentes mencionados al inicio que provee el paquete de Livewire Flux, hay muchos a lo largo de toda la aplicación que sirven para distintos propósitos, pero, su sufijo, ya ejemplifica bastante bien qué es lo que hacen, por ejemplo:
<flux:navlist>
<flux:navlist.item>
<flux:heading>
<flux:subheading>
<flux:dropdown>
<flux:profile>
<flux:menu>
<flux:input>Al final, todos estos no son más que componentes en Laravel con un montón de clases de Tailwind, así que, puedes inspeccionarlos desde el navegador; de igual forma, estos componentes los iremos empleando poco a poco a medida que avancemos.
resources/views/components/layouts/app/sidebar.blade.php
<flux:sidebar sticky stashable class="border-r border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">El resto de las acciones disponibles creadas por el instalador de Laravel tenemos acciones como cambiar la contraseña y otros datos de usuario, cerrar la cuenta, modo oscuro y poco más, esto lo tienes en el sidebar listado antes en la parte inferior:
http://livewirestore.test/settings/profile
Ruteo, vistas y página única (sin controlador tradicional)
Un componente Livewire puede reemplazar a un controlador.
Ejemplo clásico:
class Dashboard extends Component {
public function render() {
return view('livewire.dashboard');
}
}Esto simplifica la arquitectura en más de un 40% en proyectos pequeños/medianos.
Carga de archivos, validación en tiempo real y lazy loading
Características avanzadas de Livewire que suelen ser highlight del framework:
- Upload de archivos con validación previa.
- Validación instantánea con reglas del servidor.
- Lazy loading para componentes que no deben cargar al inicio.
- Query Strings sincronizable con propiedades internas: útil para filtros, tablas, paginación.
Cuando implementé carga de archivos por primera vez, me sorprendió que no tuve que escribir nada de JS para los previews y estados.
Analizando un proyecto en Livewire
La ruta apunta directo al componente, sin pasar por un controlador tradicional. La primera vez que lo hice pensé: “vaya, esto simplifica toneladas de boilerplate”.
Pero eso es solo el comienzo. Lo más importante es entender cómo se estructura un proyecto Livewire moderno, así que vayamos a eso.
Lo primero que vemos, es un par de enlaces para registrarse y login, en este punto, si ya no los has hecho, crea un usuario; una vez registrado o iniciar la sesión, tendrás acceso a:
http://livewirestore.test/dashboard
Cuya vista corresponde a:
<x-layouts.app title="Dashboard">
<div class="flex h-full w-full flex-1 flex-col gap-4 rounded-xl">
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
<div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
<x-placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
</div>
<div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
<x-placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
</div>
<div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
<x-placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
</div>
</div>
<div class="relative h-full flex-1 overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
<x-placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
</div>
</div>
</x-layouts.app>Cómo puedes apreciar, x-layout-app, corresponde a un componente en Laravel base:
resources/views/components/layouts/app.blade.php
<x-layouts.app.sidebar :title="$title ?? null">
<flux:main>
{{ $slot }}
</flux:main>
</x-layouts.app.sidebar>Lo más extraño del código anterior, es el componente que inicia con flux, los cuales, son los componentes mencionados al inicio que provee el paquete de Livewire Flux, hay muchos a lo largo de toda la aplicación que sirven para distintos propósitos, pero, su sufijo, ya ejemplifica bastante bien qué es lo que hacen, por ejemplo:
<flux:navlist>
<flux:navlist.item>
<flux:heading>
<flux:subheading>
<flux:dropdown>
<flux:profile>
<flux:menu>
<flux:input>Al final, todos estos no son más que componentes en Laravel con un montón de clases de Tailwind, así que, puedes inspeccionarlos desde el navegador; de igual forma, estos componentes los iremos empleando poco a poco a medida que avancemos.
resources/views/components/layouts/app/sidebar.blade.php
<flux:sidebar sticky stashable class="border-r border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">El resto de las acciones disponibles creadas por el instalador de Laravel tenemos acciones como cambiar la contraseña y otros datos de usuario, cerrar la cuenta, modo oscuro y poco más, esto lo tienes en el sidebar listado antes en la parte inferior:
http://livewirestore.test/settings/profile

LO que Más me GUSTA de LARAVEL (LIVEWIRE) wire:click
Quiero hablarte de lo que más me gusta de Laravel en general, aunque, señalo Livewire pero para mí por más que sea es lo mejor que tiene Laravel es simplemente esto:
wire:click="selectCategodyToDelete({{ $c }})"Para mí no hay cosa que supera esto ¿Por qué me refiero con esto? ya esto también lo comentaba un poco en otro video pero ¿qué es lo que estamos haciendo aquí ¿Qué significa el cógido anterior, recuerda que sería un archivo del cliente sé que es un PHP pero recuerda que la final se renderiza esto va a ser una vista eso es transparente para nosotros eso es la final cuando se consume desde la página en este caso es un listado va a ser algo como lo que tenemos acá tal cual un listado HTML puro HTML JavaScript y CSS que eso es lo que entiende el navegador Pero
¿qué estamos haciendo por acá ya que lo veo tan fascinante básicamente recuerda que esto viene siendo un método que tenemos en el servidor:
function selectCategodyToDelete(Category $category){
$this->categoryToDelete = $category;
}Es decir de manera directa y esa es la palabra aquí directa estamos llamando a un método del servidor.
En otros frameworks o sin Livewire, tenemos que crear la ruta, controlador y una petición mediante axios o fetch para simular la integración que tenemos el livewire:
wire:click="selectCategodyToDelete({{ $c }})"Los eventos de Livewire la clave
Por supueto, con el wire click me refiero a los eventos en general, como el de submit, es lo mismo pero lo que cambia es el evento, menciono el evento click ya que es el más genérico y usado pero, hay otros como el submit, change… que puedes buscar en la documentación oficial.
Lo segundo mejor de Laravel Livewire, sus componentes REALES
Como comentamos antes, podemos invocar algo en el servidor sin necesidad de enviar formularios o peticiones manuales con Axios o Fetch.
Con wire:click es tan simple como esto:
wire:click="nombreDelMetodo"Nada de estar creando rutas, controladores, métodos o configurando peticiones HTTP... Todo es mucho más directo, limpio y modular. Y eso es precisamente lo que más me gusta de Livewire.
Lo segundo que más me gusta son los componentes reales que podemos construir. Por eso tengo abierta esta pantalla: todo esto forma parte de mi curso/libro completo sobre Laravel Livewire, que puedes obtener en mi aplicación de academia o en otros medios.
Puedes filtrar por la sección de Laravel, darle clic a Livewire y ahí lo puedes adquirir. También está disponible en otras plataformas, como Udemy, o incluso en formato libro.
Livewire: Componentes Reales, No Solo Vistas
Aquí trabajamos con componentes reales, no simples vistas. Por ejemplo, tenemos un archivo Blade, donde referenciamos con @livewire el componente correspondiente, que es simplemente un formulario.
Este formulario tiene sus validaciones, su lógica, y todo lo demás. Por ejemplo, si quito un campo y envío, vas a ver que las validaciones se ejecutan. Puedes implementar cualquier tipo de lógica en el componente, y eso es lo que lo hace poderoso.
Pero lo que quiero destacar no es solo eso, sino el hecho de que realmente es un componente. Si no pudiéramos hacer alguna inicialización al momento de definirlo, esto no sería más que una simple vista. Es precisamente lo que ocurre con Inertia.js, y por eso no me gusta tanto.
Comparación con Inertia.js
Veamos un ejemplo: el componente Person. Aquí tenemos su clase asociada y su vista, que devolvemos en el método render. Pero lo interesante es que podemos ejecutar código PHP al momento de cargar el componente. Cualquier operación de inicialización, lo que quieras.
Por ejemplo, en el componente Contact1 (el primer paso), que es Person, colocamos un dd() o un dump para ver que efectivamente se ejecuta. No se está llamando por un click, sino por la carga del componente cuando se cumple cierta condición. Es decir, apenas se carga, se ejecuta código del servidor.
Y eso es lo que me encanta de Livewire: esa capacidad de inicialización en el servidor, al momento de montar el componente:
Controlador:
class Person extends Component
{
***
// ****
function mount($parentId)
{
$this->parentId($parentId);
}
// **** #[On('parentId')]
function parentId($id)
{
$this->parentId = $id;
$c = ContactPerson::where('contact_general_id', $this->parentId)->first();
if ($c != null) {
$this->name = $c->name;
$this->surname = $c->surname;
$this->other = $c->other;
$this->choices = $c->choices;
}
}Vista:
@elseif ($step == 2)
@livewire('volt.contact.company', ['parentId' => $pk])
@elseif ($step == 2.5)
@livewire('volt.contact.person', ['parentId' => $pk])En cambio, en Inertia.js esto no sucede. Aunque puedes devolver un componente en Vue desde Laravel, lo que realmente estás haciendo es devolver una vista. No se ejecuta nada del lado del servidor como tal. Todo sucede del lado del cliente.
Aparte de que, cuando consumimos un componente de Livewire mediante una ruta o desde la vista, SIEMPRE se ejecuta código en el servidor, a diferencia de Inertia, de que, solamente se ejecuta el código en el servidor CUANDO es una ruta más NO cuando se ejecuta desde OTRO componente en Vue.
Aunque perfectamente pudieras implementar un axios o similar desde el componente en Vue para ejecutar ese algo (lo cual NO tendría ninguna ventaja si lo comparamos con Laravel base)… estamos hablando sobre que herramienta nos da facilidades para trabajar con componentes.
¿Qué Implica Esto?
Esto significa que en Inertia, si quieres hacer alguna lógica al cargar el componente, tienes que hacerlo desde el cliente, por ejemplo en el ciclo de vida de Vue (mounted) y desde ahí disparar una petición al servidor.
Mientras que en Livewire, todo eso ya está integrado. Puedes trabajar directamente desde el backend, inicializar, consultar la base de datos, validar, formatear... lo que quieras.
Por ejemplo, cuando pasamos un identificador a un componente, también podemos pasarle toda la data, como el contacto completo. Esto lo hacemos para que el componente se “arme” correctamente. En Inertia, lo que hacemos es pasar los datos como props desde el controlador, o incluso desde la vista, aprovechando que Vue acepta esos props.
Es como un híbrido un poco extraño, pero funcional. Sin embargo, no tenemos esa ejecución directa del servidor como sí la tenemos en Livewire. En Inertia tendríamos que montar el componente y luego hacer una petición extra si queremos lógica inicial.
Cosas que NO me gustan de Laravel Livewire... Su "Complejidad"
Llegó el momento en el cual quiero hablar un poquito mal de Livewire, ya que casi siempre hablo mal de Inertia cuando los comparo. Siempre hago estas comparaciones porque se supone que son tecnologías hermanas: ambas salieron junto con Jetstream, en su primera presentación por parte del equipo de Laravel (creo que fue con la versión 7). A partir de ahí, cada una ha tomado caminos algo distintos.
Sin embargo, sigue siendo interesante compararlos, porque cuando vas a crear un nuevo proyecto en Laravel, puedes decidir entre usar:
- Laravel base,
- Laravel con Inertia + Vue,
- Laravel con Inertia + React,
- Laravel con Livewire.
No hay una mejor que otra en términos absolutos, aunque —en mi humilde opinión— Livewire es un poco más todo terreno que Inertia. Pero como siempre digo: todo tiene sus ventajas y desventajas, dependiendo del tipo de proyecto que quieras hacer.
Los "problemas" de Livewire: Complejidad y Abstracto
Ahora sí, vamos con lo que no me gusta tanto de Livewire.
La principal crítica que tengo es la complejidad que se genera entre los componentes de Laravel (Livewire), Blade y Alpine.js. Siento que todo se empieza a solapar.
Por ejemplo:
No sabes en qué momento estás trabajando con JavaScript de Livewire, y en qué momento estás en Alpine. Te muestro un caso:
<div class="flex" x-data="{ active: $wire.entangle('step') }" class="flex flex-col max-w-sm mx-auto">Cuando quieres lograr comunicación bidireccional entre cliente y servidor, terminas entrando en una maraña de x-data, @entangle, get etc. Esto no pasa en Inertia, donde simplemente defines un prop, pasas los datos y te olvidas:
<script setup>
import Layout from './Layout'
import { Head } from '@inertiajs/vue3'
defineProps({ user: Object })
</script>
<template>
<Layout>
<Head title="Welcome" />
<h1>Welcome</h1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</Layout>
</template>Aquí, sin embargo, quieres saber el valor del state, porque es el que indica el "paso por paso" de un formulario, y al actualizar el estado en el servidor, también quieres actualizarlo en el cliente. Pero como el get no lo puedes leer directamente, se pierde el valor y terminas escribiendo lógica extra solo para mantener la sincronización.
¿Más Opciones? Sí. ¿Más Código? También
La ventaja de Livewire es que al estar más integrado a Laravel, tienes más opciones. Pero esas opciones a veces hacen que el código sea más complicado de mantener.
En Inertia, como todo es directamente Vue o React, es mucho más claro qué pasa y dónde pasa. En cambio, con Livewire tienes lógica en Blade, lógica en componentes, lógica en Alpine y lógica en PHP. Cuesta seguirle el rastro a todo.
Otro caso que me resultó complicado es la comunicación entre componentes padre e hijo (y viceversa) en Livewire.
Por ejemplo, en el componente de "paso por paso", que forma parte del curso y libro que puedes buscar en academia, tengo un StepEvent que se lanza desde el hijo, y lo escucha el padre. El padre es el componente general, y los hijos son:
// parent
class General extends Component
{
protected $listeners = ['stepEvent'];
}
//child
class Company extends Component
{
***
function back() {
$this->dispatch('stepEvent', 1);
}Cuando se está en uno de esos pasos y el usuario interactúa, el hijo lanza un evento al padre. El padre escucha con un @listener y ejecuta el método correspondiente.
Esto puede resultar confuso la primera vez que alguien lo lee, sobre todo si no conoce nuestro código. ¿Cómo documentas algo así? Se vuelve complicado.
Comunicación Inversa: Padre a Hijo
En el curso/libro también mostré otro ejemplo más interesante: el carrito de compras.
Tienes un componente Cart (padre) que contiene varios CartItem (hijos).
Pero esta vez, quiero que el padre pase información hacia el hijo, concretamente el post o ítem del carrito:
// parent
class Cart extends Component
{
function addItem()
{
$this->dispatch('addItemToCart', $this->post);
}
}
// child
class CartItem extends Component
{
***
#[On('addItemToCart')]
function add(Post $post, int $count = 1)
{***}Como es una entidad que se maneja en el padre, necesito pasarla hacia el hijo para que lo agregue o modifique. No quiero complicarte aquí con el detalle técnico, pero básicamente es eso.
¿Demasiadas Opciones?
No estoy criticando por criticar, me encanta Livewire. Pero sí tiene una curva de aprendizaje más alta si lo comparamos con Inertia, y es precisamente por estas lógicas que pueden parecer algo abstractas.
Además, hay múltiples formas de hacer lo mismo.
Por ejemplo:
Cuando trabajas con filtros y eventos, puedes definirlos como:
- Etiquetas con @,
- Decoradores como @url,
- O directamente como propiedades públicas.
Esto te da más opciones, pero también hace más complicada la programación.
Entonces, puedes ver más claramente la diferencia entre:
- Un componente real, como lo vemos en Livewire, con lógica en cliente y servidor integrados.
- Un componente de Vue en Inertia, que en realidad es una vista que requiere lógica manual para hablar con el servidor.
Buenas prácticas que debes seguir
Performance y carga diferida
- Usa lazy cuando posible (wire:model.lazy).
- Divide componentes grandes en subcomponentes.
- Evita renderizados innecesarios usando ->skipRender().
- Carga scripts solo cuando se necesiten.
SEO, accesibilidad y experiencia de usuario
Aunque Livewire no es un framework SPA completo, sí soporta:
- metas dinámicas
- títulos por página
- navegación rápida
- componentes accesibles (especialmente con Flux UI)
Realmente, puedes usar aspectos de Livewire junto con Laravel clásico y esta web es un ejemplo de eso, para el Dashboard uso Laravel Livewire, para el blog, uso Laravel base.
Testing, mantenimiento y escalabilidad
- Usa pruebas con Livewire::test().
- Mantén un naming consistente entre componentes y vistas.
- Versiona componentes UI.
- Evita mezclar demasiada lógica en un solo componente (máximo 1 responsabilidad).
En resumen: trabajar con Livewire hoy se siente moderno, flexible y mucho más simple que antes aunque lamentablemente, ya no hay disponible opciones predefinidas antes con Jetstream como carga de avatar, sesión, roles/equipos.
Jetstream el legado
Livewire en sus orígenes usaba Jetstream que era varias funcionalidades que podíamos usar de gratis que te voy a listar a continuación, pero, en la evolución que ha tenido Livewire ya NO viene con Livewire:
Que permiten los equipos de Laravel Livewire
- Los equipos son un mecanismo para agrupar usuarios bajo un perfil en particular; por lo tanto, un usuario pertenece a un o varios equipos, que puede ser el equipo que se cree de manera automática cuando creamos el usuario.
Gestión de Tokens de autenticación
- Desde la opción de API Tokens podemos generar Tokens de autenticación que podemos emplear en cualquier otra aplicación, para esto recuerda que empleamos Laravel Sanctum.
Jetstream, Livewire y Tailwins.CSS
- Este paquete emplea por defecto el framework CSS conocido como tailwind.css, el cual al igual que Bootstrap nos ofrece un completo conjunto de clases para personalizar nuestra interfaz; pero, la diferencia fundamental con este último, radica en la que NO tenemos componentes; no tenemos componentes como cartas, botones, y prácticamente nada de lo que aparece en la sección de componentes de Bootstrap.
- Pero mediante estas clases nosotros podemos construir estos componentes; esto tiene su lado bueno y malo al mismo tiempo:
- El lado bueno es que podemos crear una interfaz con un mayor nivel de personalización que podemos hacer en Bootstrap, ya que Bootstrap con componentes existentes si los queremos cambiar tuviéramos que sobrescribir reglas CSS.
- El lado malo es precisamente el efecto que se obtiene del primer punto; al ser un diseño más manual tenemos que pasar un tiempo creando estos componentes y por lo tanto un desarrollo más lento.
FAQs: Preguntas frecuentes sobre proyectos Livewire
- ¿Livewire reemplaza a Vue o React?
- Depende del tipo de proyecto: para paneles internos y CRUDs sí, para apps ultra interactivas no.
- ¿Puedo usarlo junto con Alpine.js?
- Sí, es una combinación muy común.
- ¿Es adecuado para proyectos grandes?
- Sí, especialmente con componentes bien divididos. La comunidad en Reddit comparte buenas experiencias en proyectos medianos/grandes.
- ¿Qué cambia en Laravel 12?
- Volt y Flux pasan a ser parte del ecosistema Livewire moderno, y Jetstream ya no incluye tantas funciones predefinidas.
Ahora, vamos a conocer la pieza clave de Livewire, los componentes.