Skip to main content
Laravel 11 introduced the “Slim Application Skeleton,” which significantly changed the application structure. This FAQ covers points that can be confusing when you join a project that has already been upgraded, or when you learned Laravel from books and tutorials written for Laravel 10 or earlier. These are questions frequently asked on Laracasts forums and Stack Overflow around the time Laravel 11 was released.
This FAQ targets new projects (Laravel 11 and later). For upgrading an existing project, see the Migration Guide.
In the new structure, config files that are rarely changed have been removed from the project. The framework’s own config/ directory is used for those files.The project-side config/ and the framework-side config/ are merged, with the project side taking precedence. You can create a file at any point when customization is needed and it will be picked up.
In the new structure, App\Http\Controllers\Controller is an empty class — it does not extend Illuminate\Routing\Controller and does not use the ValidatesRequests or AuthorizesRequests traits.Reference: Laravel 10 Controller vs Laravel 11 ControllerAlternative approaches:
If you use these frequently, you can restore App\Http\Controllers\Controller to the Laravel 10 style:
In the new structure, app/Http/Kernel.php has been removed. Middleware configuration is now done via withMiddleware() in bootstrap/app.php.
Custom middleware files themselves are still created in app/Http/Middleware/.
$this->middleware() is a feature of Illuminate\Routing\Controller. It is not available in the new structure’s empty base controller.Instead, implement the HasMiddleware interface and define a middleware() method:
In Laravel 13 and later, you can also use the #[Middleware] attribute:
Reference: Controller middleware
authorizeResource() depends on the AuthorizesRequests trait, which is not included in the new structure’s empty base controller.There are several ways to address this.1. Restore the base controller to the Laravel 10 style (easiest)
This makes $this->authorizeResource() available again.2. Use the #[Authorize] attribute on each method (Laravel 13+)
In the new structure, app/Console/Kernel.php has been removed. The location for defining scheduled tasks has changed.Define schedules in routes/console.php (recommended):
Define schedules in bootstrap/app.php:
In the new structure, EventServiceProvider has been removed, and manual event and listener registration is no longer required.Auto-discovery: Declare the event class as a type hint on the handle() method of your listener class, and it will be registered automatically.
If you need to register manually, do it in AppServiceProvider::boot():
In the new structure, the list of service providers moved from config/app.php to bootstrap/providers.php.
Providers created with artisan make:provider are automatically added to this file.
In the new structure, app/Exceptions/Handler.php has been removed. Exception handling is now configured via withExceptions() in bootstrap/app.php.
Route customization is done via withRouting() in bootstrap/app.php.Adding a route file:
Full control (equivalent to Laravel 10’s RouteServiceProvider):Specifying using disables Laravel’s default route registration entirely, giving you full control.
Add a providers key to config/app.php. It will be merged with the framework’s own config/app.php and take effect.
The replace() method lets you swap a default provider with your own implementation.
Starting with Laravel 11, API functionality is not included by default — install it separately when you need it.
This command creates and configures the following:
  • routes/api.php
  • Laravel Sanctum for API authentication
  • API route registration in bootstrap/app.php
Starting with Laravel 11, broadcasting is also not included by default — install it separately when you need it.
This command creates and configures the following:
  • routes/channels.php
  • Laravel Reverb installation and configuration
  • Broadcasting configuration file
Check the contents of bootstrap/app.php.Laravel 11+ new structure (or migrated):
Legacy structure upgraded from Laravel 10 or earlier:
If the file starts with return Application::configure(..., it uses the new structure. Otherwise, the project was upgraded from the legacy structure. To migrate a legacy project to the new structure, see the Migration Guide.

Laravel 11+ Application Structure

A full breakdown of the new application structure and the internals of ApplicationBuilder.

Migration Guide: Old Structure to Slim Application Skeleton

Step-by-step guide to migrating a Laravel 10 application from the legacy structure to the Slim Application Skeleton.
Last modified on May 4, 2026