Hasina Razafintsalama

Hasina RAZAFINTSALAMA

← Back to Blog
Backend

Laravel 13: What Changed Compared to Laravel 12

Laravel 13 lands with a first-party AI SDK, native PHP attributes, and JSON:API support. Here is what actually matters if you are upgrading from Laravel 12.

2026-07-08·11 min

Laravel 13 shipped on March 17, 2026, and it raises the minimum PHP version to 8.3. Beyond the version bump, the release leans in two directions: making cross-cutting configuration explicit with PHP attributes, and giving every Laravel app a first-party way to talk to LLMs and to serve the JSON:API spec. This is what changed compared to Laravel 12, and whether it is worth upgrading.

Laravel 12 vs Laravel 13 at a glance

AreaLaravel 12Laravel 13
Minimum PHP8.28.3
LLM integrationCommunity packages (Prism, openai-php)First-party AI SDK
Job and command configClass propertiesPHP attributes, optional, in 15+ places
JSON:APIHand-rolled or a packageFirst-party JsonApiResource
CSRF middlewareVerifyCsrfTokenPreventRequestForgery, origin-aware
Queue routingScattered onQueue() and onConnection()Centralised Queue::route()
ReleasedFebruary 2025March 2026

Read the table as a summary. Every row is expanded below, with what it replaces and when it matters.

A first-party AI SDK

The biggest headline is the Laravel AI SDK: a unified API for text generation, tool-calling agents, embeddings, audio and images across providers. Instead of wiring the OpenAI or Anthropic packages yourself and building your own abstraction, you get one Laravel-native interface, with a provider prefix, that stays the same whichever provider you swap in. It includes streaming, structured output, and a testing fake so you do not hit a real API in your test suite.

php
use Laravel\Ai\Facades\Ai;

$response = Ai::text()
    ->using('anthropic:claude-sonnet-5')
    ->prompt('Summarize this changelog in one sentence.')
    ->generate();

echo $response->text;

It replaces community packages like Prism and openai-php/laravel, and the hand-rolled Guzzle wrappers many teams built. If you only ever call one provider, a thin wrapper is still fine; the SDK earns its place when you want provider portability or the agent and tool-calling primitives.

PHP attributes instead of class properties

Laravel 13 introduces attribute syntax as an optional alternative to property-based configuration in more than 15 places: models, controllers, jobs, commands, listeners, mailables, notifications. The point is not to replace conventions, it is to put cross-cutting configuration, the queue name, the retry count, model scopes, observers, on the class declaration instead of as loose public properties buried in the body.

php
// Laravel 12: configuration scattered across properties
class SendInvoice implements ShouldQueue
{
    public $queue = 'invoices';
    public $tries = 3;
    public $backoff = 30;
}

// Laravel 13: configuration declared where the class is declared
#[Queueable(queue: 'invoices', tries: 3, backoff: 30)]
class SendInvoice implements ShouldQueue
{
}

It is opt-in, and both styles work side by side. The upside is discoverability and better static analysis; the cost, during the transition, is a second way to configure the same thing, so pick one convention per project and apply it consistently.

JSON:API resources, natively

The JSON:API spec, resource objects, relationships, sparse fieldsets, links, compound documents, pagination metadata, is a lot of boilerplate to hand-roll and easy to get subtly wrong. Laravel 13 ships a first-party JsonApiResource that produces a spec-compliant response, including the correct content type, from a simple declaration of the type, id, attributes and relationships.

php
class UserResource extends JsonApiResource
{
    public function toArray(Request $request): array
    {
        return [
            'type' => 'users',
            'id' => (string) $this->id,
            'attributes' => [
                'name' => $this->name,
                'email' => $this->email,
            ],
        ];
    }
}

This matters only if you actually target the JSON:API spec, usually because a client or a standard requires it. For a plain REST API, the existing Eloquent API Resources are simpler and there is no reason to switch.

Hardened CSRF with PreventRequestForgery

The request-forgery protection middleware has been reworked and renamed PreventRequestForgery. It adds origin-aware verification on top of the existing token check, which closes a class of cross-origin bypass, useful now that more Laravel apps expose an API consumed by a first-party SPA and a mobile client side by side. Standard Blade forms keep working unchanged; the thing to check on upgrade is any custom middleware or test that referenced VerifyCsrfToken by its old name.

Centralised queue routing

Instead of scattering onQueue() and onConnection() calls across job classes and dispatch sites, the new Queue::route() method declares the connection and queue for each job class in one place, typically a service provider. It makes it easy to see at a glance which jobs run where, and to change the routing without editing the jobs themselves.

php
// AppServiceProvider::boot()
Queue::route(SendInvoice::class, connection: 'redis', queue: 'invoices');
Queue::route(GenerateReport::class, connection: 'sqs', queue: 'reports');

How to upgrade from Laravel 12

  • Bump PHP to 8.3 first, as its own change, and get that green in CI before touching the framework.
  • Follow the official upgrade guide. For most apps it is a Composer version bump plus a handful of renames and config moves.
  • Search the codebase for VerifyCsrfToken and update references to PreventRequestForgery.
  • Leave the AI SDK, attribute configuration and JsonApiResource for later, on their own branches. None of them is required by the upgrade itself.

Laravel 12 keeps receiving bug fixes until August 13, 2026 and security fixes until February 24, 2027. There is no rush. Upgrade when one of the new features solves a problem you have, or to stay on the current major before the support window narrows.

Should you upgrade now?

If you are not building AI features or a public JSON:API, the day-to-day difference between Laravel 12 and 13 is small, and the attribute syntax is the change most teams will feel. The upgrade itself is low-risk: mostly a Composer bump once PHP 8.3 is in place. The reason to do it is currency, not because Laravel 12 is about to break.

FAQ

What is the difference between Laravel 12 and Laravel 13?

Laravel 13 raises the minimum PHP version to 8.3 and adds four notable first-party features: an AI SDK, JSON:API resources, attribute-based configuration, and centralised queue routing, plus a hardened CSRF middleware. Everything else is incremental.

Is upgrading to Laravel 13 hard?

For a typical app, no. It is mostly a Composer version bump and a few renames. The bigger prerequisite is PHP 8.3, which you should handle as a separate step first.

Do you have to use the Laravel AI SDK?

No. It is an optional package. If you already use Prism or an OpenAI package and it works for you, there is no obligation to switch.

When does Laravel 12 stop being supported?

Bug fixes until August 2026, security fixes until February 2027. You have time, but the window is not open forever.

Laravel 13 is an evolutionary release: the same framework, with AI and API-spec work brought in-house and a nudge toward explicit configuration. Upgrade for currency, and adopt the new features when they earn their place in your codebase.

Need help with this topic? Full Stack Development

Discover this service