skip to content

What did Laravel 11's slim application skeleton change for new apps, and does an app upgraded from Laravel 10 have to adopt it?

level: middleimportance: should knowfreq 45%

answer

  1. fewer files in new apps
  2. kernels configured in bootstrap/app.php
  3. one AppServiceProvider
  4. config, api and broadcasting opt-in
  5. upgraded apps may keep the old layout

basics

~20 s

Laravel 11 gave new apps a much smaller skeleton: no app-level kernel classes, middleware and exceptions configured in bootstrap/app.php, one service provider, and opt-in config, API and broadcasting files. Upgraded apps may keep their Laravel 10 structure.

solid answer

~40 s

Laravel 11's slim skeleton moved configuration that used to live in generated classes into the framework and into `bootstrap/app.php`. A new app has no `app/Http/Kernel.php`, `app/Console/Kernel.php` or exception handler class: routing, middleware and exception handling are set up with `withRouting()`, `withMiddleware()` and `withExceptions()`. Providers shrink to `AppServiceProvider`, listed in `bootstrap/providers.php`. Most config files are no longer published (`config:publish` brings one back), `routes/api.php` and broadcasting are opt-in, and a `/up` health route is registered. The framework kept the old pieces, so an app upgraded from 10 does **not** have to adopt the new structure; the kernel classes and `RouteServiceProvider` still exist in Laravel 13. Laravel 12 and 13 kept this skeleton.

go deeper

for a junior

Know that new apps configure routing, middleware and exceptions in bootstrap/app.php and list providers in bootstrap/providers.php.

for a middle

Map each Laravel 10 file to its Laravel 11+ replacement, and explain that the framework's own kernels still do the work.

for a senior

Decide whether an upgraded app should restructure, and plan it as a separate, test-backed change that reproduces middleware order exactly.

for a principal

Set a convention across apps: whether older apps converge on the slim structure, and when, so onboarding and documentation match what developers find.

## Before and after Up to Laravel 10, `laravel new` generated a lot of framework wiring as application code: two kernel classes, an exception handler and five service providers. Most teams never edited most of it. Laravel 11 moved that wiring back into the framework and left a much smaller application. | Concern | Laravel 10 skeleton | Laravel 11+ skeleton | |---|---|---| | HTTP middleware | `app/Http/Kernel.php` | `withMiddleware()` in `bootstrap/app.php` | | Exception handling | `app/Exceptions/Handler.php` | `withExceptions()` in `bootstrap/app.php` | | Console kernel, schedule | `app/Console/Kernel.php` | `routes/console.php` and the framework's kernel | | Route loading | `RouteServiceProvider` | `withRouting(web:, commands:, health:)` | | Service providers | five in `app/Providers` | `AppServiceProvider`, listed in `bootstrap/providers.php` | | Config files | every file published | ten published; the rest opt-in with `config:publish` | | API routes, broadcasting | files present by default | opt-in with install commands | | Health check | none | `/up` route | Other defaults changed at the same time, such as SQLite and database-backed sessions, cache and queue in a fresh `.env`. ## What stayed the same The request still passes through an HTTP kernel, and scheduled commands still run through a console kernel. The difference is that the framework's own kernel classes are used directly, and `Application::configure()` passes your routing, middleware and exception settings to them. The concepts an interviewer asks about (middleware groups, providers, exception reporting) are unchanged; only where you declare them moved. ## Upgraded apps: keep or move? The key upgrade fact is that **an upgraded app does not have to adopt the slim structure**. The framework still ships: - the HTTP and console kernel base classes that `app/Http/Kernel.php` and `app/Console/Kernel.php` extend; - the `RouteServiceProvider`, `AuthServiceProvider` and `EventServiceProvider` base classes; - the ability to build the application the Laravel 10 way in `bootstrap/app.php`. So a municipal permit portal upgraded from 10 to 13 can keep its kernel and providers. Reasons to move anyway: 1. **Consistency** with new apps and current documentation, which shows the slim form. 2. **Less code**: the old kernel mostly repeated framework defaults. 3. **New configuration hooks** documented only for `bootstrap/app.php`. Reasons to wait: - It is a structural change with no user-visible benefit, and mixing it into a version upgrade makes failures harder to trace. - Middleware order and groups must be re-created exactly, which needs good test coverage. A sensible plan is: upgrade versions first, then restructure in a separate change, moving one concern at a time (for example, middleware first, then exceptions, then the schedule). ## How to restructure safely When the team does decide to move an upgraded app to the slim form, the order matters: 1. Create a new `bootstrap/app.php` using `Application::configure()` and copy route loading from `RouteServiceProvider` into `withRouting()`. 2. Recreate the middleware groups, aliases and global middleware in `withMiddleware()`, comparing the resulting order with the old kernel. 3. Move reporting and rendering rules from the exception handler into `withExceptions()`. 4. Move scheduled tasks into `routes/console.php`, then delete the old kernel and provider classes. Each step can ship on its own, with the test suite run in between. ## Why the change mattered for the release line The slim skeleton is the reason later upgrades are smaller. With defaults living in the framework, a change of default reaches every app that did not override it, without a file to update; and the skeleton that the upgrade guides compare against has fewer files to diff. Laravel 12 and 13 kept the same structure, which is why both were described as small upgrades. ## Mistakes interviewers listen for - Saying Laravel 11 **removed** kernels from the framework: it removed them from the skeleton. - Saying an upgrade to 11 or later **requires** restructuring. - Describing `app/Http/Kernel.php` as the place to register middleware in a **new** Laravel 13 app. - Forgetting that a missing config file does not mean a missing setting; the framework supplies it.

  • In a new Laravel 13 app, where do you register a global middleware, since there is no app/Http/Kernel.php?
    In `bootstrap/app.php`, inside the closure passed to `withMiddleware()`, using the `Middleware` configuration object it receives (for example `$middleware->append(...)`). The framework's HTTP kernel applies that configuration when the app is created.
  • Why did the slim skeleton make later Laravel upgrades smaller?
    Defaults that used to be copied into every app as classes and config files now live in the framework. An app that never overrode them has nothing to update when they change, and the skeleton diff reviewed during an upgrade covers far fewer files.

saying these in an interview costs you the question

  • Laravel 11 deleted the kernel classes from the framework
  • Upgrading to Laravel 11 forces an app to move to bootstrap/app.php
  • A new Laravel 13 app registers middleware in app/Http/Kernel.php
  • The slim skeleton removed middleware groups and service providers as concepts
  • Laravel 12 brought the old kernel-based skeleton back