Laravel 11's headline change isn't a new feature so much as a restructuring: a much slimmer default application skeleton, with most of the boilerplate that used to live in app/Http/Kernel.php, multiple service providers, and scattered config files consolidated into bootstrap/app.php. If you've maintained a Laravel app across several major versions, this is the release where the framework finally acted on years of "why do new projects start with so many files nobody touches."
The slimmer application skeleton
A fresh Laravel 11 install no longer ships a separate Kernel.php for HTTP or console, no default app/Console/Kernel.php, and far fewer service provider files — middleware registration, exception handling, and route model binding customisation all move into a fluent, chainable configuration inside bootstrap/app.php. Existing Laravel 10 apps aren't forced onto this structure when upgrading; the old structure still works, it's specifically new projects that get the leaner skeleton. If you're maintaining an older app, the practical upgrade work is dependency version bumps, not a structural rewrite.
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->throttleApi();
})
->withExceptions(function (Exceptions $exceptions) {
$exceptions->report(function (InvalidOrderException $e) {
// custom reporting
});
})->create();
Built-in health check routing
The health: '/up' line above is new in Laravel 11 — a zero-config health check endpoint that returns a 200 as long as the application booted, useful for load balancer and container orchestrator health probes without writing a custom route and controller for it. It's intentionally minimal (it doesn't check database or cache connectivity by default), so for a real production readiness probe you still want your own endpoint that checks the dependencies that actually matter to you.
Per-second rate limiting
Laravel's rate limiter previously only supported per-minute granularity. Laravel 11 adds per-second rate limits, which matters for APIs where a per-minute cap is too coarse to stop a short burst from overwhelming a downstream service — think a webhook receiver or a third-party API proxy where you need to smooth traffic within a single second, not just across a minute.
RateLimiter::for('webhooks', function (Request $request) {
return Limit::perSecond(5)->by($request->ip());
});
php artisan make:class and php artisan make:enum were added for scaffolding plain classes and native PHP enums consistently with the rest of Laravel's generators, and php artisan about --only=environment style filtering makes the diagnostics command more useful in CI scripts than parsing the full table output.
Model casts as a method instead of a property
Eloquent models can now define an optional casts() method instead of (or alongside) the $casts property, which lets you build cast definitions dynamically — passing arguments to a custom cast class, for example — something the static array property couldn't express. The old $casts property still works; this is additive, not a deprecation.
protected function casts(): array
{
return [
'options' => AsCollection::class,
'status' => OrderStatus::class,
'discount' => AsEncryptedCollection::class,
];
}
What upgrading from Laravel 10 actually involves
Laravel 11 requires PHP 8.2 minimum, and if you're on an LTS-adjacent app you're mostly checking that your dependencies (Sanctum, Horizon, third-party packages) have released Laravel 11-compatible versions before running composer update. The skeleton changes don't force a rewrite of an existing app's structure — you keep your Kernel.php files if you have them — so the real upgrade cost is almost entirely dependency compatibility, not adapting to the new conventions.
Wrapping up
Laravel 11's real contribution is subtraction: a smaller default skeleton, consolidated configuration in bootstrap/app.php, plus genuinely useful additions like per-second rate limiting, zero-config health routing, and method-based casts. None of it forces existing applications to restructure — the new skeleton only applies to fresh installs — so upgrading is mostly a dependency-compatibility exercise rather than a rewrite.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.