News

What We Know About Laravel 14

Published
What We Know About Laravel 14 image

Laravel 14 is the next major release of the Laravel framework, expected in Q1 2027. This release will require PHP 8.4 as the minimum version and will follow Laravel's standard support cycle, with bug fixes through Q3 2028 and security updates through Q1 2029.

The Laravel team has not announced a release date or a feature list yet. Everything below comes from the master branch of laravel/framework, where Laravel 14 development happens, and any of it can change before the release.


New Features

Laravel 14 features will be added to this post as they are announced. Most new features still ship in the weekly Laravel 13 minor releases, and the features below wait for Laravel 14 because they add a method to a contract or change a signature.

Route::query()

#60655 by Vazha Aptsiauri adds routing support for the HTTP QUERY method, a safe method that carries a request body:

Route::query('/search', function () {
return request()->input('filter');
});

Route::any() includes QUERY, and the CSRF middleware treats it as a read request, the same as GET, HEAD, and OPTIONS.

Laravel 13.19 already added Http::query() to the HTTP client, along with the query() and queryJson() testing helpers.

For Laravel 13, check out our tutorial on the HTTP QUERY method with Scout search.

$user->authorize()

Will Rowe added an authorize() method to the Authorizable contract and trait in #59708:

// Laravel 13
Gate::forUser($user)->authorize('viewAny', Post::class);
 
// Laravel 14
$user->authorize('viewAny', Post::class);

It works like $user->can(), but throws an AuthorizationException when the check fails.

Context for report()

The report() helper and the exception handler's report() method accept an optional context array, added by Caleb White in #60767:

try {
$order->charge();
} catch (Throwable $e) {
report($e, ['order_id' => $order->id]);
}

The ExceptionHandler contract changes to report(Throwable $e, array $context = []), so a custom handler that overrides report() needs the new parameter.

Storage::fake() for On-Demand Disks

Storage::fake('ondemand') intercepts Storage::build() calls, so you can test on-demand disks with the same assertions as named disks (#61378). The PR was sent to master because an application might already have a disk named ondemand.

orWhereKey() and Subqueries in whereKey()

Caleb White consolidated whereKey() and whereKeyNot() and added orWhereKey() and orWhereKeyNot() in #61395. A second PR, #61496, lets all four methods accept a subquery.

Breaking Changes

Queue Pause Methods Take the Queue First

Laravel 13.25 added the ability to pause all queues, and the per-queue methods on the Queue facade require the connection as the first argument. #61076 moves the connection to the end and defaults it to the default connection:

// Laravel 13
Queue::pause('redis', 'emails');
Queue::pauseFor('redis', 'emails', 60);
 
// Laravel 14
Queue::pause('emails');
Queue::pauseFor('emails', 60);
Queue::pause('emails', 'redis');

resume() and isPaused() also take the queue first and an optional connection second.

lazy() and chunk() No Longer Mutate the Builder

In Laravel 13, lazy() and chunk() change the query builder as they paginate. Reusing the same builder afterward returns the wrong result:

$query = User::query();
 
foreach ($query->lazy(2) as $user) {
// ...
}
 
$query->count(); // 0 in Laravel 13

Jack Bayliss fixed both methods in #61411 and #61428, so count() returns the full number of rows in Laravel 14.

findOr() With an Array of IDs

Builder::findOr() never called its callback when you passed an array of IDs. #61577 by Matthieu makes it match findOrFail() and the relationship versions of findOr():

User::findOr([1, 99], fn () => 'fallback');
 
// Laravel 13: a Collection containing only user 1
// Laravel 14: 'fallback'

Cache::has() and Cache::forget() With Arrays

The docblocks for has() and forget() have accepted arrays for four years, but Cache::has(['a', 'b']) always returned true, and Cache::forget(['a', 'b']) did not remove the keys. #61466 by Jack Bayliss fixes both methods. In Laravel 14, has() returns true only when every key exists:

Cache::put('foo', 'bar');
 
Cache::has(['foo', 'missing']);
 
// Laravel 13: true
// Laravel 14: false

Passing an array to forget() removes every key, and it returns true only when every key was removed:

Cache::forget(['foo', 'baz']);
 
// Laravel 13: the keys remain, and the Redis store emits an
// "Array to string conversion" warning
// Laravel 14: both keys are removed

MassPrunable Includes Soft-Deleted Models

The Prunable trait adds withTrashed() to the prune query when a model uses soft deletes. MassPrunable did not, and #61425 makes them consistent. Take a model that uses both traits:

use Illuminate\Database\Eloquent\MassPrunable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
 
class Post extends Model
{
use MassPrunable, SoftDeletes;
 
public function prunable()
{
return static::where('created_at', '<=', now()->subMonth());
}
}

In Laravel 13, model:prune force deletes the matching posts that are not soft-deleted, and the soft-deleted posts stay in the table. In Laravel 14, it force deletes every matching post, including the soft-deleted ones.

If you use MassPrunable on a soft-deleting model, check that your prunable() query still selects the rows you expect. To keep the Laravel 13 behavior, add withoutTrashed() to the query.


PHP Version Requirements

Laravel 14 will require PHP 8.4 as the minimum version, an increase from Laravel 13's PHP 8.3 minimum. In #59104, Laravel 14 increases the minimum version to PHP 8.4, because Symfony 8 requires PHP 8.4 as a minimum.

Laravel will also work with newer versions of PHP. See What's New in PHP 8.6 for the rest of that release.

Other dependency changes on master likely to land in Laravel 14:

  • ably/ably-php moves to the version that uses Ably protocol 2.0 (#60860)
  • orchestra/testbench-core moves to ^12.0
  • PHPUnit 11.5, 12.5, and 13 are all supported

Support Timeline

Laravel's support policy outlines major releases shipping every year around the first quarter. Following that policy, Laravel 14 will receive bug fixes until Q3 2028 and security updates until Q1 2029:

Version PHP (*) Release Bug Fixes Until Security Fixes Until
11 8.2 - 8.4 March 12th, 2024 September 3rd, 2025 March 12th, 2026
12 8.2 - 8.5 February 24th, 2025 August 13th, 2026 February 24th, 2027
13 8.3 - 8.5 March 17th, 2026 Q3 2027 March 17th, 2028
14 8.4+ Q1 2027 Q3 2028 Q1 2029

Note: The official docs do not list Laravel 14 yet, official details TBD.

Laravel 13, released March 17, 2026, will continue receiving:

  • Bug fixes until Q3 2027
  • Security fixes until March 17, 2028

Laravel 12 no longer receives bug fixes, and its security fixes end on February 24, 2027.

Upgrading to Laravel 14

If you want to automate the upgrade when Laravel 14 is released, check out Laravel Shift. Shift opens a pull request with atomic commits for you to review.

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Sponsored

acquaintsoft logo
Acquaint Softtech

Hire Laravel developers with AI expertise at $20/hr. Get started in 48 hours.

Visit Acquaint Softtech

The latest

View all →
Difflock: Lint Laravel Migrations and Diff Your Schema image

Difflock: Lint Laravel Migrations and Diff Your Schema

Read article
Fresh Package: Laravel Package Skeleton with Testbench, CI, and Boost Integration image

Fresh Package: Laravel Package Skeleton with Testbench, CI, and Boost Integration

Read article
Inertia DevTools Now Available for Firefox image

Inertia DevTools Now Available for Firefox

Read article
Laravel Scalpel Scans for Filesystem Intrusion Evidence image

Laravel Scalpel Scans for Filesystem Intrusion Evidence

Read article
Mercure Broadcasting in Laravel 13.32 image

Mercure Broadcasting in Laravel 13.32

Read article
Super Stack: Laravel Starter Kit With Filament and NativePHP image

Super Stack: Laravel Starter Kit With Filament and NativePHP

Read article