Laravel 11: Main New Features and Changes

Laravel 11 is one of the most exciting versions of the framework for a long time. Quite a lot of changes and new features, let's explore them!


1. Slim Skeleton

The most significant change for Laravel 11 is the more minimalistic application skeleton.

When you install a new Laravel project, the folder structure will look like this:

app/
├── Http/
│ └── Controllers/
│ └── Controller.php
├── Models/
│ └── User.php
└── Providers/
└── AppServiceProvider.php
bootstrap/
├── app.php
└── providers.php
config
...

NOTE: These structure changes are OPTIONAL. They will be the default only for NEW projects. Older Laravel applications can have the old structure.

Removed folders: app/Console, app/Exceptions, app/Http/Middleware.

Routes, Middlewares, and Exceptions are now registered in the bootstrap/app.php file.

bootstrap/app.php:

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
 
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();

Also, cleaned up routes folder. The files routes/channel.php, routes/console.php, and routes/api.php have been removed.

You can check the initial pull request [11.x] Slim skeleton to see more details on what was changed.


2. Removed Some Config Files

This change has a backstory. At first, when Taylor introduced slimmer skeleton, all config/ files were removed. However, Taylor wasn't happy with this change and introduced a slimmer config version.

So, if you look at the config/ folder of Laravel 10, you will find these files missing in Laravel 11:

  • config/broadcasting.php
  • config/cors.php
  • config/hashing.php
  • config/sanctum.php
  • config/view.php

But you can publish them manually, with this command:

php artisan config:publish

Or:

php artisan config:publish --all

Also, some config values inside the existing files were removed in favor of automations inside the framework itself.

Now, speaking about Sanctum and Broadcasting configuration...


3. API and Broadcasting: Installed Optionally

Laravel 11 has no routes/api.php file, and Sanctum isn't installed by default. You can install the API scaffolding with the php artisan install:api artisan command.

When you run this artisan command, the routes/api.php file will be created and registered in the bootstrap/app.php, and Laravel Sanctum will be installed. You must only add the Laravel\Sanctum\HasApiTokens trait to the User Model.

Similarly to the API changes, broadcasting also became installable: to prepare the application, you can use the php artisan install:broadcast artisan command.


4. New Defaults: Pest and SQLite

With Laravel 11, there are a few new default settings.

Testing Framework: Pest

Taylor made a poll on X (Twitter), and the majority of the people voted for Pest to be the default testing framework, so it was changed.

Notice: if you want to start with testing, we have a course Testing in Laravel 11 For Beginners where we specifically use Pest syntax first, but also have PHPUnit examples.

Default Database: SQLite

The default database for Laravel was changed to SQLite. You can check the pull request SQLite for local dev. Also, watch my YouTube video Upcoming Laravel 11: SQLite as Default Database about this change.

If you want to change the default database driver to MySQL, we have an article about it.


5. New "make:xxxxx" Commands

Laravel 11 comes with new make: artisan commands. Now, you can create enums, interfaces, and classes.

php artisan make:enum
php artisan make:class
php artisan make:interface

You can check the syntax in GitHub pull requests:


6. Health Check

Laravel 11 comes with a new registered Route /up.

bootstrap/app.php:

return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
channels: __DIR__.'/../routes/channels.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();

Laravel defines the health route when setting the routes and fires the DiagnosingHealth Event.

src / Illuminate / Foundation / Configuration / ApplicationBuilder.php:

use Illuminate\Foundation\Events\DiagnosingHealth;
use Illuminate\Support\Facades\View;
 
class ApplicationBuilder
{
// ...
 
protected function buildRoutingCallback(?string $web,
?string $api,
?string $pages,
?string $health,
string $apiPrefix,
?callable $then)
{
return function () use ($web, $api, $pages, $health, $apiPrefix, $then) {
if (is_string($api) && realpath($api) !== false) {
Route::middleware('api')->prefix($apiPrefix)->group($api);
}
 
if (is_string($health)) {
Route::middleware('web')->get($health, function () {
Event::dispatch(new DiagnosingHealth);
 
return View::file(__DIR__.'/../resources/health-up.blade.php');
});
}
 
if (is_string($web) && realpath($web) !== false) {
Route::middleware('web')->group($web);
}
 
if (is_string($pages) &&
realpath($pages) !== false &&
class_exists(Folio::class)) {
Folio::route($pages, middleware: $this->pageMiddleware);
}
 
if (is_callable($then)) {
$then($this->app);
}
};
}
 
// ...
}

The /up endpoint returns the response time.


7. Dumpable Trait

Laravel 11 introduces a new Dumpable trait. It is intended to replace the current dd() and dump() methods in most of the framework's classes. Users and package authors can include this trait for easier code debugging.

Here is the usage example:

use Illuminate\Support\Traits\Conditionable;
use Illuminate\Support\Traits\Dumpable;
 
class Address
{
use Conditionable, Dumpable;
 
// ...
}
$address = new Address;
 
$address->setThis()->setThat();
$address->setThis()->dd()->setThat();

See the pull request on GitHub: [11.x] Adds Dumpable concern


8. Limit Eager Load

Laravel 11 will allow limiting eagerly loaded records natively, without external packages.

class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
class Post extends Model
{
// ...
}
$users = User::with(['posts' => function ($query) {
$query->latest()->limit(10);
}])->get();

Before Laravel 11, you needed a separate package Eloquent Eager Limit by Jonas Staudenmeir.

See the pull request on GitHub: [11.x] Support eager loading with limit.


9. Casts Method

From Laravel 11, the casts will be provided in the protected method casts() instead of the protected property $casts.

class User extends Authenticatable
{
// ...
 
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}

Also, now it is possible to provide an array.

protected function casts(): array
{
return [
'bookOptions' => [AsCollection::class, OptionCollection::class],
];
}

This is a non-breaking change. You only need to know that the casts() method is prioritized over the $casts property.

See the pull request on GitHub: [11.x] Adds Model::casts() method and named static methods for built-in casters.


10. once() Method

There's a new memoization function called once(). This function ensures that a callable is called only once, returning the same result on subsequent calls.

class User extends Model
{
public function stats(): array
{
return once(function () {
// Expensive operations to generate user stats, multiple db queries, etc...
 
return $stats;
});
}
}
// Assuming you have two User instances: $userA and $userB
 
$userA->stats();
$userA->stats(); // cached result from previous line...
 
$userB->stats(); // Not using $userA cached results, because $userB !== $userA
$userB->stats(); // cached result from previous line...

See the pull request on GitHub: [11.x] Adds once memoization function.


11. New Welcome Page

Laravel 11 comes with a new welcome page. The images below show how it looks in light and dark mode.

Laravel 11 welcome page light mode

Laravel 11 welcome page dar mode


Last but not least: Minimum PHP 8.2

Finally, Laravel 11 dropped support for PHP 8.1. Now, PHP 8.2 is the minimum requirement. See the pull request on GitHub: [11.x] Drop PHP 8.1 support.


Upgrade Guide and/or Shift

So, if you want to upgrade your applications to Laravel 11 and use the new features, read the official documentation upgrade guide. Or, if you want to automate the upgrade process, you can use a service like Laravel Shift.

Keep in mind that the skeleton changes are optional, the old syntax functionality still works and isn't removed or deprecated. So you may upgrade to Laravel 11 and still continue using the old folder/code structure.


Did I miss anything important? Pretty sure there are more minor tweaks and small new features in Laravel 11, which I will cover in separate tutorials.

avatar

thanks a lote <3

avatar

Very informative!

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 59 courses (1056 lessons, total 44 h 09 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials