What Changed in Laravel 13.25
Running php artisan dev spins up four processes at once: the development server, a queue worker, Pail, and Vite. Before Laravel 13.25, all four wrote to the same terminal stream via concurrently, making it easy to lose a stack trace in a wall of Vite rebuild output.
Laravel 13.25 replaces concurrently with @laravel/multiplex, a purpose-built terminal UI that keeps every process in its own lane. No installation, no configuration — just run:
php artisan dev
Three Display Modes
Tabs (default) gives each process its own tab. You read one process at a time, can restart or clear logs per-tab, and a crashed process restarts automatically without taking the others down.
Stream is the classic interleaved view, but now scrollable and searchable instead of relying on your terminal's scrollback buffer.
Inline emits plain output with no UI. It activates automatically when there is no TTY, making it the right choice for containers, CI pipelines, and process supervisors.
Select a mode for a single run with a flag or its short form:
php artisan dev --tabs # -t
php artisan dev --stream # -s
php artisan dev --inline # -i
You can also toggle between tabs and stream while the UI is running. Add timestamps to any mode:
php artisan dev --timestamps
When you quit, everything buffered is printed to the terminal in stream style — no output is lost.
Setting Project-Wide Defaults
Per-run flags are for one-offs. Lock in defaults for the whole team in a service provider:
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();
}
}
The full set of configuration methods:
| Method | Effect |
|---|---|
| DevCommands::tabs() | One tab per process (default) |
| DevCommands::stream() | Interleaved scrollable feed |
| DevCommands::inline() | Plain output, no UI |
| DevCommands::withTimestamps() | Prefix every line with a timestamp |
| DevCommands::disableAutoRestart() | Leave crashed processes dead |
| DevCommands::bufferSize(5000) | Lines kept per process in tabs mode |
| DevCommands::streamBufferSize(10000) | Total lines kept in stream mode |
Command-line flags always win over provider settings, so --tabs overrides DevCommands::stream() for that run.
Auto-Restart Behavior
Previously, artisan dev passed --kill-others-on-fail to concurrently, meaning one dying process killed the entire stack. The new default restarts only the crashed process. Fix the file and the process comes back on its own.
To revert to fail-fast behavior for a single run:
php artisan dev --no-restart
Or permanently with DevCommands::disableAutoRestart().
Platform Requirements and the JSON Flag
The multiplex terminal UI runs on macOS and Linux only. Windows continues to use concurrently; the mode and buffer methods are no-ops there, though --timestamps and --no-restart are translated to equivalent concurrently flags.
Node v22.13 or later is required. The framework pins @laravel/multiplex to a specific minor version and runs it through your project's package manager (pnpm dlx or npx) — nothing to add to package.json.
For tooling integrations, a structured output flag is available:
php artisan dev --json
This emits newline-delimited JSON events (implying --inline) and is intended for editor extensions or dashboards that consume structured process output.
The SERVER_HOST Fix
A related fix in the same release corrects SERVER_HOST being ignored. The default server process was registered as serve --host=localhost, which overrode the environment variable. It is now registered as plain serve, so this works again:
SERVER_HOST=0.0.0.0 php artisan dev
Key Takeaways
@laravel/multiplexreplacesconcurrentlyin Laravel 13.25 with no setup required- Three modes: tabs (default), stream, and inline (auto-selected without a TTY)
- Crashed processes restart automatically; use
--no-restartto disable - Project-wide defaults live in a service provider via
DevCommandsmethods - Buffer sizes are configurable to prevent chatty processes from pushing out other logs
- macOS/Linux only for the TUI; Windows keeps using
concurrently SERVER_HOSTenvironment variable now works correctly again
Source: Laravel Terminal UI for the artisan dev Command — Laravel News