What's New in Laravel 13: A Complete Overview

· 5 min read

Laravel 13 is officially released today! This is the next major release after Laravel 12, bringing powerful features and significant improvements. Let's walk through the most important changes you need to know.

System Requirements

Before upgrading, check the basic requirements:

Component Minimum
PHP 8.3+ (8.4 recommended)
Composer 2.8+
Node.js 20+

Laravel 13 officially drops support for PHP 8.2, so this is a good time to upgrade PHP if you haven't already.

1. Completely Revamped Starter Kits

Laravel 13 fully refreshes the starter kits with more choices:

laravel new my-app

You'll get to choose from these stacks:

  • React + TypeScript (with Inertia v2)
  • Vue + TypeScript (with Inertia v2)
  • Livewire + Volt (default)
  • API Only (no frontend)

Each starter kit comes with either WorkOS AuthKit or Laravel's built-in auth for authentication, along with pre-configured Tailwind CSS v4.

2. Eloquent: Typed Model Attributes

One of the most anticipated changes — Eloquent models now support explicitly declared typed attributes:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\Column;

class Post extends Model
{
    #[Column(type: 'string')]
    public string $title;

    #[Column(type: 'datetime')]
    public Carbon $published_at;

    #[Column(type: 'boolean')]
    public bool $is_active;
}

Your IDE will recognize types immediately without PHPDoc or @property. This pairs beautifully with PHP 8.4 Property Hooks.

3. Fluent Validation Rules

Validation rules can now be chained fluently:

use Illuminate\Validation\Rule;

$rules = [
    'email' => Rule::string()->email()->unique('users')->max(255),
    'age' => Rule::integer()->min(18)->max(120),
    'role' => Rule::string()->in(['admin', 'editor', 'viewer']),
];

No more pipe separators or messy arrays. Code becomes clearer, more readable, and IDE-friendly.

4. Artisan Console Improvements

Interactive Menu

php artisan make:model

Now displays an interactive menu letting you choose:

  • Create migration alongside
  • Create factory
  • Create seeder
  • Create policy
  • Create controller (resource/API/invokable)

artisan inspect

A new command for quickly checking application status:

php artisan inspect

# Output:
# Laravel 13.0.0 | PHP 8.4.18
# Environment: production
# Cache: file (hit rate: 94.2%)
# Queue: redis (3 pending, 0 failed)
# Routes: 48 registered
# Models: 12 detected

5. Upgraded Queue Batching

Batches now support conditional branching — continue processing based on results:

use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;

Bus::batch([
    new ProcessOrder($order),
])
->then(function (Batch $batch) {
    // All jobs succeeded
    Bus::dispatch(new SendConfirmation($batch->data['order_id']));
})
->onPartialFailure(function (Batch $batch) {
    // Some jobs failed, but not all
    Bus::dispatch(new NotifyAdmin($batch->failedJobs));
})
->catch(function (Batch $batch) {
    // Everything failed
})
->dispatch();

onPartialFailure is a new callback — very useful for order processing batches or bulk notifications.

6. Blade Component Auto-Discovery

Blade components are now auto-discovered — no manual registration needed:

resources/views/components/
    alert.blade.php           → <x-alert />
    ui/button.blade.php       → <x-ui.button />
    forms/input.blade.php     → <x-forms.input />

For class-based components, just place them in app/View/Components/ and Laravel finds them automatically:

// app/View/Components/Ui/Card.php
// Automatically available: <x-ui.card />

No more Blade::component() calls in AppServiceProvider.

7. Caching: Stale-While-Revalidate

This popular web caching pattern is now natively supported in Laravel:

Cache::flexible('posts', [300, 600], function () {
    return Post::published()->get();
});

The [300, 600] parameter means:

  • 0–300 seconds: return cached value immediately
  • 300–600 seconds: return stale cache to user, refresh in background
  • After 600 seconds: force regeneration

This is the best way to keep responses fast while ensuring fresh data.

8. Testing Improvements

assertJsonStructureStrict

$response->assertJsonStructureStrict([
    'data' => [
        '*' => ['id', 'name', 'email'],
    ],
]);

Unlike assertJsonStructure, the strict version ensures no extra fields — useful for verifying APIs don't leak sensitive data.

Improved Parallel Testing

php artisan test --parallel --processes=8

Laravel 13 optimizes database seeding in parallel mode, significantly reducing test suite execution time.

9. Extended Route Model Binding

Support for binding multiple models with custom resolvers:

Route::get('/teams/{team}/projects/{project}', function (Team $team, Project $project) {
    // $project is automatically scoped to $team
})->scopeBindings();

The scopeBindings() feature existed before, but Laravel 13 extends it to support automatic nested scoping up to 3 levels:

Route::get('/org/{org}/team/{team}/member/{member}', function (
    Organization $org,
    Team $team,
    Member $member
) {
    // member belongs to team, team belongs to org — automatically validated
})->scopeBindings();

10. Performance

Notable performance improvements:

  • Route caching 40% faster with a new serialization format
  • Eloquent hydration 25% faster when loading models from database
  • Container resolution improved — reduced overhead when resolving dependencies
  • View compilation happens once and is cached permanently (until changed)

Upgrading From Laravel 12

Using Laravel Shift is the fastest way:

# Or upgrade manually
composer require laravel/framework:^13.0

Key breaking changes to watch for:

  1. PHP 8.2 is no longer supported
  2. Some methods deprecated in L12 have been removed — check the changelog
  3. New config files — run php artisan config:publish to update
  4. Old validation rules still work but will be deprecated in L14

See the Upgrade Guide for full details.

Summary

Laravel 13 is an update focused on developer experience and performance. Typed model attributes, fluent validation, and stale-while-revalidate caching are three features I'll be adopting immediately. If you're running Laravel 12, upgrading is the right call.

Which feature excites you the most? Give it a try and share your experience!

Comments