Skip to content
Muhammet Şafak
tr
Framework & Library 3 min read

Laravel 11's New Slim Skeleton Structure

A look at Laravel 11's leaner skeleton, the defaults that were removed, and the concrete impact on everyday development workflows.


Laravel 11 shipped in March 2024, and its most noticeable change wasn’t a technical feature: the skeleton structure was significantly trimmed down. My initial reaction — and I suspect this was shared by many Laravel developers — was a mild sense of disorientation. File locations and registration points that had become muscle memory over years had moved.

After a few days of working with it, though, I realized this wasn’t a superficial reorganization. It was a deliberate principle: “you shouldn’t ship what you don’t use.”

What was removed, what was simplified

In Laravel 10 and earlier, app/Http/Kernel.php was the central registration point for the middleware stack. Under app/Providers/ you’d find several service provider files waiting for you: AppServiceProvider, AuthServiceProvider, EventServiceProvider, RouteServiceProvider. Start a new project and they were just there — whether you needed them or not.

With Laravel 11, a significant portion of those files was removed or consolidated. Middleware registration now happens through a more fluent API in bootstrap/app.php. AuthServiceProvider and EventServiceProvider no longer ship by default; you create them when you actually need them.

// bootstrap/app.php — Laravel 11 approach
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->append(EnsureTokenIsValid::class);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        // custom exception handling
    })
    ->create();

If you know the old Kernel.php approach, this feels less indirected. Everything lives in one file, readable as a chain.

Models beyond app/Models/User.php

There’s no radical change on the model side, but User.php now starts out leaner by default. Cast definitions and fillable field lists are more minimal out of the box. I think that’s the right call: consciously choosing what your starting point contains beats the “it was already there” assumption.

A single service provider

In Laravel 10, registration logic was scattered across multiple service provider files. Now it all converges in a single AppServiceProvider. Event listeners go there, authorization gates go there.

// app/Providers/AppServiceProvider.php
public function boot(): void
{
    Gate::define('update-event', function (User $user, Event $event) {
        return $user->id === $event->user_id;
    });

    Event::listen(EventCreated::class, SendEventNotification::class);
}

This reduces file count but creates conditions for AppServiceProvider to bloat. As a project grows, writing separate service provider classes still makes sense — but not having unnecessary files land by default is a good starting point.

Broadcast channels and queue configuration

Broadcast channels can now be defined directly via a service provider or a dedicated file, rather than defaulting to routes/channels.php. Queue connection configuration has been simplified along similar lines.

These changes introduce some learning friction on first setup, but the underlying question they’re asking is: “What does this project actually need?”

The upgrade experience

I set aside a day to migrate the Looplio API layer to Laravel 11. The laravel/upgrade package is a solid starting point — it lists the majority of breaking changes. The area that needs the most attention: the signatures of custom middleware classes changed. The $request and $next parameters are the same, but the Illuminate namespace for the handle() method’s type hints shifted.

The transition definitely creates some friction, but at the end of it you have fewer files and fewer “what was this for?” moments. Two weeks in, the new structure already felt natural.

Overall assessment

Laravel 11’s skeleton simplification isn’t a feature — it’s a philosophy decision. Along the tension between “zero configuration, zero excess” and “everything ready to go,” the framework took a step toward the former.

For small projects, this likely means a few unnecessary files you never had to delete. For larger projects, it means building the habit of consciously choosing what you add. In both cases, it makes sense.

Tags: #Laravel
Share:

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

Related Posts

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind