The artisan dev Command and What's New in Laravel 13.16.0
Laravel #Laravel #Laravel 13 #Artisan #PHP #Release

The artisan dev Command and What's New in Laravel 13.16.0

3 min read Mohamed Said Mohamed Said

What's New in Laravel 13.16.0

Laravel 13.16.0 landed on June 17, 2026 with a handful of developer-experience improvements. Here is a breakdown of every notable addition.

The php artisan dev Command

The headline feature is a new php artisan dev command that starts your development processes—server, queue worker, log tailing, and Vite—concurrently in a single terminal. Its default behavior mirrors the existing composer dev script, but configuration now lives in your application code rather than composer.json.

Register commands through the DevCommands class, typically inside a service provider:

use Illuminate\Foundation\Console\DevCommands;

DevCommands::artisan('reverb:start');
DevCommands::register('stripe listen --forward-to ' . config('app.url'));

You can name a process explicitly and assign a terminal color:

DevCommands::artisan('reverb:start', 'reverb')->orange();
DevCommands::register('stripe listen --forward-to ' . config('app.url'))->green();

Packages inside vendor cannot register commands automatically, keeping the list under your control. A companion NodePackageManager helper detects the correct package manager (npm, yarn, pnpm, or bun) from the lockfiles present, so generic commands resolve to the right runner.

Note: Upgrade to v13.16.1, which contains a bug fix for registering the artisan dev command.

whenFilledEnum() on Requests

The InteractsWithData trait gains a whenFilledEnum() method that converts a request value to a backed enum before invoking a callback. It replaces the manual whenFilled()tryFrom() → null-check pattern:

$request->whenFilledEnum('status', Status::class, function (Status $status) use ($query): void {
    $query->where('status', $status);
});

The callback fires only when the key is present, the class is a backed enum, and tryFrom() returns a valid case. Invalid values are silently skipped. An optional second callback runs as a fallback:

$request->whenFilledEnum(
    'status',
    Status::class,
    fn (Status $status) => $query->where('status', $status),
    fn () => $query->where('status', Status::Active)
);

withCookies() on All Responses

withCookies() has been promoted from RedirectResponse to ResponseTrait, making it available on every response type including JsonResponse:

return response()->json($data)->withCookies([$cookieA, $cookieB, $cookieC]);

The change is fully additive and non-breaking.

Array Maintenance Mode Driver

A new array driver joins the existing file and cache drivers for maintenance mode. It targets parallel testing scenarios where the file driver or Cache facade mocking can interfere with php artisan up and down calls.

Other Notable Changes

  • Enums in broadcastAs() — broadcast events can now return an enum for the event name, keeping names consistent across sender and receiver.
  • JSON Schema anyOf support — plus a guard against unbounded $ref expansion to prevent runaway recursion in the deserializer.
  • Fixed shell quoting when scheduled commands run as another user.
  • Added support for queue attributes on traits.
  • Improved return types across model scopes, connection callbacks, and callback-passthrough helpers.

Key Takeaways

  • php artisan dev centralizes concurrent dev-process management inside your app code.
  • whenFilledEnum() removes boilerplate when filtering requests by backed enum values.
  • withCookies() is now available on any response, not just redirects.
  • The array maintenance mode driver makes parallel test suites more reliable.
  • Upgrade to v13.16.1 to pick up the artisan dev registration fix.

Source: Laravel News — The artisan dev Command in Laravel 13.16.0

Found this useful?

Frequently Asked Questions

3 questions
Q01 What does `php artisan dev` do in Laravel 13.16.0?
It starts your development processes—local server, queue worker, log tailing, and Vite—concurrently in one terminal. You configure which processes run by registering them via the `DevCommands` class in a service provider, keeping that configuration inside your application rather than in `composer.json`.
Q02 How is `whenFilledEnum()` different from `whenFilled()` on a Laravel request?
`whenFilledEnum()` automatically calls `tryFrom()` on the raw input value and passes a fully typed backed-enum instance to your callback. It silently skips invalid values and accepts an optional fallback callback, eliminating the manual `tryFrom()` and null-check steps you would need with plain `whenFilled()`.
Q03 Why was an `array` maintenance mode driver added?
The file-based driver and `Cache` facade mocking can conflict in parallel test runs when tests call `php artisan up` or `down`. The new `array` driver keeps maintenance state in memory for the duration of the test process, avoiding those conflicts.

Continue reading

More Articles

View all