php artisan dev arranca cuatro procesos en un solo terminal: el servidor de desarrollo, un worker de colas, Pail y Vite. Hasta la 13.25 todos escribían en el mismo flujo, cosa que funciona hasta que Vite recompila mientras el worker registra un job y tú estás intentando leer un stack trace de Pail.
El comando delegaba en concurrently, y Laravel 13.25 lo sustituye por @laravel/multiplex, una interfaz de terminal que mantiene cada proceso separado. No hay nada que instalar ni que configurar: php artisan dev lo usa directamente.
Requisitos
Laravel 13.25 o superior, publicada el 11 de agosto de 2026.
Node 22.13 o superior, que es el mínimo de
@laravel/multiplex.macOS o Linux. En Windows el comando sigue funcionando con
concurrently.
El framework fija el paquete a una versión menor concreta y lo ejecuta con el comando exec de tu gestor de paquetes, así que un proyecto con pnpm ejecuta pnpm dlx y uno con npm ejecuta npx, sin configuración de por medio. No añades ninguna dependencia a tu package.json.
Los tres modos
Tabs es el modo por defecto. Cada proceso registrado tiene su pestaña y vas cambiando entre ellas para leer uno cada vez. Se pueden reiniciar procesos individuales o limpiar sus logs sin tocar el resto, y un proceso que se cae vuelve solo.
Los atajos están en la barra inferior: tab cambia de pestaña, las flechas hacen scroll, c limpia el log de la pestaña activa, / busca, s salta a modo stream y q sale. El reinicio de un proceso concreto es r, y deja constancia en el log con una línea del tipo Restarted at 06:37:55 mientras las demás pestañas siguen a lo suyo.
Stream es el comportamiento antiguo con mejores herramientas: un único flujo entremezclado, pero desplazable y con búsqueda, en lugar de depender de lo que el scrollback de tu terminal haya guardado.
Inline es salida plana, sin interfaz. Se selecciona automáticamente cuando no hay TTY, que es lo que quieres si artisan dev corre bajo un supervisor de procesos, dentro de un contenedor o en CI.
Para una ejecución concreta:
php artisan dev --tabs
php artisan dev --stream
php artisan dev --inlineLas formas cortas son -t, -s e -i. También puedes cambiar entre tabs y stream con la interfaz en marcha, así que el flag solo hace falta cuando quieres empezar en un modo distinto al de por defecto.
La búsqueda funciona tanto en tabs como en stream, y los timestamps se pueden activar en cualquier modo:
php artisan dev --timestampsAl salir del comando, todo lo que estaba en el buffer se imprime en el terminal principal en formato stream. Cerrar la interfaz no tira a la basura la salida que estabas mirando.
Fijar el modo por defecto del proyecto
Los flags por ejecución están bien para casos puntuales. Si quieres que todo el equipo trabaje en modo stream, o que los timestamps salgan siempre, se configura en el boot de un service provider, al lado de tus registros de procesos:
<?php
namespace App\Providers;
use Illuminate\Foundation\DevCommands;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
if (! $this->app->environment('local')) {
return;
}
DevCommands::stream();
DevCommands::withTimestamps();
}
}Hay siete métodos para configurar el comando:
Método | Qué hace |
|---|---|
| Una pestaña por proceso (por defecto) |
| Un flujo único, entremezclado y desplazable |
| Salida plana, sin interfaz |
| Antepone un timestamp a cada línea |
| Deja muerto el proceso que falle |
| Líneas guardadas por proceso en modo tabs |
| Líneas guardadas en total en modo stream |
Los flags de línea de comandos ganan sobre el provider, así que php artisan dev --tabs sobrescribe una llamada a DevCommands::stream(), y --no-restart sobrescribe el reinicio automático en esa ejecución.
Los dos tamaños de buffer son lo que más merece pensarse. En modo tabs cada proceso tiene su propio buffer circular, de forma que un Vite muy hablador no puede empujar fuera de la vista la salida del worker, que es justo lo que pasa en un scrollback compartido. Sube bufferSize() si te encuentras llegando al tope de una pestaña.
Reinicio automático
Un proceso que se cae vuelve a arrancar solo. Es un cambio real de comportamiento respecto al --kill-others-on-fail que artisan dev pasaba a concurrently desde la 13.18, donde la muerte de un proceso se llevaba por delante todo el conjunto.
El nuevo comportamiento por defecto encaja con el caso habitual: un worker que muere por un error fatal mientras editas la clase de un job, o Vite cayéndose por un import mal escrito. Arreglas el archivo y el proceso vuelve sin que tengas que reiniciar nada. Cuando prefieras ver el fallo y parar:
php artisan dev --no-restartO de forma permanente con DevCommands::disableAutoRestart().
En Windows, los métodos de modo y de buffer no hacen nada, pero --timestamps y --no-restart se traducen a los flags equivalentes de concurrently, así que esos dos funcionan en cualquier plataforma.
Queda un flag más, pensado más para herramientas que para leerlo tú:
php artisan dev --jsonEmite eventos en JSON delimitado por saltos de línea en lugar de salida formateada, e implica --inline. Es el punto de enganche para envolver artisan dev en otra cosa: una extensión de editor o un panel que quiera salida estructurada de los procesos.
El arreglo de SERVER_HOST
En la misma versión ha entrado un cambio relacionado. El proceso server por defecto se registraba como serve --host=localhost, y como una opción explícita en línea de comandos gana sobre el valor por defecto que ServeCommand saca del entorno, SERVER_HOST dejó de tenerse en cuenta cuando el esqueleto de la aplicación pasó del script composer dev a artisan dev. Exponer el servidor de desarrollo a otro dispositivo de tu red dejó de funcionar.
Ahora el valor por defecto es serve a secas, así que esto vuelve a comportarse como antes:
SERVER_HOST=0.0.0.0 php artisan devSi habías registrado tu propio proceso server para esquivar el problema, ya lo puedes borrar.
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción