New updates and improvements to Laravel's open source products.
Laravel 13 continues Laravel's annual release cadence with a focus on AI-native workflows, stronger defaults, and more expressive developer APIs. This release includes first-party AI primitives, JSON:API resources, semantic / vector search capabilities, and incremental improvements across queues, cache, and security.
Laravel 13 introduces the first-party Laravel AI SDK, providing a unified API for text generation, tool-calling agents, embeddings, audio, images, and vector-store integrations.
With the AI SDK, you can build provider-agnostic AI features while keeping a consistent, Laravel-native developer experience.
For example, a basic agent can be prompted with a single call:
1use App\Ai\Agents\SalesCoach;2 3$response = SalesCoach::make()->prompt('Analyze this sales transcript...');4 5return (string) $response;
The Laravel AI SDK can also generate images, audio, and embeddings:
For visual generation use cases, the SDK offers a clean API for creating images from plain-language prompts:
1use Laravel\Ai\Image;2 3$image = Image::of('A donut sitting on the kitchen counter')->generate();4 5$rawContent = (string) $image;
For voice experiences, you can synthesize natural-sounding audio from text for assistants, narrations, and accessibility features:
1use Laravel\Ai\Audio;2 3$audio = Audio::of('I love coding with Laravel.')->generate();4 5$rawContent = (string) $audio;
And for semantic search and retrieval workflows, you can generate embeddings directly from strings:
1use Illuminate\Support\Str;2 3$embeddings = Str::of('Napa Valley has great wine.')->toEmbeddings();
Laravel now includes first-party JSON:API resources, making it straightforward to return responses compliant with the JSON:API specification.
JSON:API resources handle resource object serialization, relationship inclusion, sparse fieldsets, links, and JSON:API-compliant response headers.
For security, Laravel's request forgery protection middleware has been enhanced and formalized as PreventRequestForgery, adding origin-aware request verification while preserving compatibility with token-based CSRF protection.
Laravel 13 adds queue routing by class via Queue::route(...), allowing you to define default queue / connection routing rules for specific jobs in a central place:
1Queue::route(ProcessPodcast::class, connection: 'redis', queue: 'podcasts');
Laravel 13 continues to expand first-party PHP attribute support across the framework, making common configuration and behavioral concerns more declarative and colocated with your classes and methods.
Notable additions include controller and authorization attributes like #[Middleware] and #[Authorize], as well as queue-oriented job controls like #[Tries], #[Backoff], #[Timeout], and #[FailOnTimeout].
For example, controller middleware and policy checks can now be declared directly on classes and methods:
1<?php 2 3namespace App\Http\Controllers; 4 5use App\Models\Comment; 6use App\Models\Post; 7use Illuminate\Routing\Attributes\Controllers\Authorize; 8use Illuminate\Routing\Attributes\Controllers\Middleware; 9 10#[Middleware('auth')]11class CommentController12{13 #[Middleware('subscribed')]14 #[Authorize('create', [Comment::class, 'post'])]15 public function store(Post $post)16 {17 // ...18 }19}
Additional attributes have also been introduced across Eloquent, events, notifications, validation, testing, and resource serialization APIs, giving you a consistent attribute-first option in more areas of the framework.
Laravel now includes Cache::touch(...), which lets you extend an existing cache item's TTL without retrieving and re-storing its value.
Laravel 13 deepens its semantic search story with native vector query support, embedding workflows, and related APIs documented across search, queries, and the AI SDK.
These features make it straightforward to build AI-powered search experiences using PostgreSQL + pgvector, including similarity search against embeddings generated directly from strings.
For example, you may run semantic similarity searches directly from the query builder:
1$documents = DB::table('documents')2 ->whereVectorSimilarTo('embedding', 'Best wineries in Napa Valley')3 ->limit(10)4 ->get();
Inertia v3 is here — a ground-up rethink of the developer experience with a focus on zero-config setup, smaller bundles, and powerful new primitives for building modern apps. Axios and qs have been replaced with a built-in XHR client, SSR works automatically during development without a separate Node process, and a new Vite plugin eliminates nearly all boilerplate. On top of that, v3 introduces optimistic updates, instant visits, standalone HTTP requests via useHttp, layout props, and fine-grained exception handling — all designed to make Inertia apps feel faster to build and faster to use. Here's what's new:
A new @inertiajs/vite plugin eliminates the boilerplate that traditionally lived in your app entry point — no more manual resolve, setup, or separate SSR entry files. Pages auto-resolve from ./Pages, code splitting and lazy-loading are handled automatically, and SSR is wired up with zero config. Your app entry point can be as simple as createInertiaApp() with no arguments. A new withApp callback also lets you modify the root app instance (register plugins, provide values) before rendering, on both client and server.
SSR now works automatically during npm run dev — no separate Node.js process required. Pages are server-rendered out of the box in development, while the production workflow (vite build && vite build --ssr) remains unchanged. Error reporting has been overhauled: errors now log the component name, URL, and actionable hints, and a SsrRenderFailed event is dispatched for monitoring. You can also disable SSR on specific routes via middleware or the Inertia facade.
Axios and qs have been removed as dependencies entirely. A lighter built-in XHR client handles all HTTP communication, reducing bundle size and the dependency footprint. If you rely on Axios interceptors or other Axios-specific features, an adapter is available to keep things working during your migration.
A new useHttp hook brings useForm-like ergonomics to plain HTTP requests outside of Inertia's page lifecycle. It provides reactive state management, error handling, file upload progress tracking, and request cancellation — ideal for API calls, external service requests, or any HTTP interaction that doesn't involve an Inertia page visit. It also supports optimistic updates and Precognition out of the box.
UI updates now apply immediately before server confirmation via a chainable .optimistic() method. Your callback receives current props and returns the optimistic values, which are applied instantly. When the server responds, real data takes over seamlessly — and if the request fails, changes auto-revert. Multiple concurrent optimistic updates are tracked independently, and the feature works across router visits, <Form>, useForm, and useHttp.
Navigate to a target page component immediately while the server request fires in the background. The page renders right away using shared props, giving the user an instant transition, and page-specific props merge in when the server responds. This is especially effective for pages where the layout and shell can render before data-heavy content arrives.
Layouts now receive props directly as regular component props via a tuple syntax: layout: [AppLayout, { title: 'Dashboard' }]. Pages can derive layout props dynamically from page data using a callback, and update them at any time via setLayoutProps(). This eliminates the need for event buses or provide/inject patterns. Named layouts and nested layouts are fully supported.
Inertia::handleExceptionsUsing() gives full control over how exceptions like 404s and 500s are rendered — including exceptions that occur outside of Inertia's middleware. Use withSharedData() to explicitly include shared props in error pages, or return null to fall through to Laravel's default exception rendering.
Inertia::optional(), Inertia::defer(), and Inertia::merge() now work inside nested arrays with dot-notation support for partial reloads, giving you more granular control over which parts of your response are loaded and when.
TypeScript generics on the <Form> component provide type-safe errors and slot props, improving the developer experience for TypeScript users.
New <x-inertia::app> and <x-inertia::head> Blade components serve as alternatives to the @inertia and @inertiaHead directives. <x-inertia::app> accepts an optional id attribute (defaults to "app"), and <x-inertia::head> supports a fallback slot for when SSR is unavailable.
The event system has been renamed for clarity: invalid is now httpException and exception is now networkError, with corresponding per-visit callbacks onHttpException and onNetworkError.
Supports Vite 7 and 8, with Vite 6 dropped. The internal utility library has also been migrated from lodash-es to es-toolkit, a modern tree-shakable alternative (raising the minimum JS target to ES2022).
Read the upgrade guide: https://inertiajs.com/docs/v3/getting-started/upgrade-guide
Our first-party starter kits have all been upgraded to use Laravel 13 and Inertia v3 from day one. Spin up a fresh app with the latest stack today!
We also shipped the new Teams feature across all starter kit flavors, giving you out-of-the-box team management screens for creating teams, switching between teams, inviting members, and updating team details.
Pull request by @meirdick
When a provider runs out of credits or hits a quota limit, Laravel AI now automatically fails over to your next configured provider instead of throwing an exception. Billing errors from Anthropic, OpenAI, OpenRouter, and DeepSeek are all detected and routed through the standard failover mechanism - no code changes required.
Pull request by @shafimsp
Agents can now pass provider-specific options - like OpenAI's reasoning.effort - by implementing the new HasProviderOptions interface. This is especially useful for reasoning models where the default effort level may burn unnecessary tokens for simple tasks:
1use Laravel\Ai\Contracts\Agent; 2use Laravel\Ai\Contracts\HasProviderOptions; 3 4class MyAgent implements Agent, HasProviderOptions 5{ 6 use Promptable; 7 8 public function providerOptions(): array 9 {10 return [11 'reasoning' => ['effort' => 'low'],12 ];13 }14}
laravel-best-practices SkillPull request by @pushpak1300
A new built-in skill covering 125+ best practices across 21 categories, from database performance and security to caching, testing, and deployment. Your AI agent now has a comprehensive reference for writing idiomatic Laravel code.
add-skill CommandPull request by @pushpak1300
When you install a third-party skill, Boost now runs a non-blocking security audit via partner services. Results appear as a color-coded table so you can make an informed decision before proceeding. Skip it anytime with --skip-audit:
1php artisan boost:add-skill owner/repo --all2php artisan boost:add-skill owner/repo --all --skip-audit
Pull request by @pushpak1300
A new MCP prompt that walks your AI assistant through upgrading from Laravel 12.x to 13.0. It auto-registers for apps running Laravel 12 and disappears once the upgrade is complete.
UpgradeInertiaV3 Prompt for Inertia v2 to v3 UpgradesPull request by @pushpak1300
Similar to the Laravel 13 upgrade prompt, this one provides step-by-step guidance for moving from Inertia v2 to v3. It detects your frontend framework (React, Vue, or Svelte) and renders only the relevant migration steps.
Pull request by @HeathNaylor
Boost's log reading tools now auto-detect JSON-formatted logs and parse them correctly. If you're using Monolog's JsonFormatter, LogstashFormatter, or LogglyFormatter, the LastError and ReadLogEntries tools handle them seamlessly alongside standard PSR-3 logs.
--discover Flag to boost:updatePull request by @MrPunyapal
Running php artisan boost:update --discover now detects new guideline packages and skills that have been published since your last update, prompting you to select which ones to add.
Pull request by @dringrayson
Amp is now a supported AI agent in Boost. Running boost:install will detect and configure the MCP server for Amp automatically, bringing it to parity with Claude Code, Cursor, Windsurf, and others.
DatabaseSchema ToolPull request by @sulimanbenhalim
The DatabaseSchema tool now accepts a summary parameter that returns only table names and column types - roughly 83% fewer tokens. AI agents can call summary first for an overview, then drill down with filter on specific tables when they need the full picture.
Pull request by @vpratfr
Stories can now reference other stories, making it easy to compose complex deployment workflows from reusable building blocks:
1@story('deploy') 2 build 3 migrate 4@endstory 5 6@story('full-deploy') 7 deploy 8 clear-caches 9 notify-team10@endstory
Pull request by @joetannenbaum
The Livewire starter kit now ships with Caleb Porzio's Blaze compiler, resulting in up to 97% reduction in compilation overhead.
Pull request by @pushpak1300
MCP tools can now return images and audio natively. A new Response::fromStorage() method auto-detects content type from your Laravel filesystem and handles the base64 encoding for you:
1// From raw binary data2Response::image($rawBytes, 'image/png');3Response::audio($rawBytes, 'audio/wav');4 5// From any Laravel disk with automatic MIME detection6Response::fromStorage('photos/avatar.jpg');7Response::fromStorage('recordings/clip.mp3', disk: 's3');
Pull request by @axlon
A new TokenCan attribute lets you declare required token scopes directly on controller methods:
1class PhotoController2{3 #[TokenCan('read')]4 public function index() { /* ... */ }5 6 #[TokenCan('write')]7 public function store() { /* ... */ }8}
Pull request by @timacdonald
You can now add custom middleware to Passport's registered routes via config - great for enforcing rules like UUID validation on client_id before it ever hits the database.
Pint/phpdoc_type_annotations_only Custom RuleAn opt-in rule that strips all PHPDoc comments except type annotations. Enable it in your pint.json:
1{2 "Pint/phpdoc_type_annotations_only": true3}
Before:
1/**2 * Register any application services.3 */4public function register(): void
After:
1public function register(): void
Type annotations like @var list<string> are preserved. The config directory is excluded by default. Best suited for new projects - enable with care on existing codebases.
fully_qualified_strict_types RuleNow enabled by default in the Laravel preset, this improvement automatically converts fully qualified class names in PHPDoc annotations to regular imports:
1+ use Database\Factories\UserFactory;2 3 class User extends Authenticatable4 {5- /** @use HasFactory<\Database\Factories\UserFactory> */6+ /** @use HasFactory<UserFactory> */7 use HasFactory, Notifiable;
This applies automatically when you update Pint.
fetch ClientPull request by @pascalbaljet
Precognition v2 ships with a built-in fetch-based HTTP client, dropping Axios as a hard dependency and reducing bundle size by up to 50%. The new client handles XSRF tokens, FormData conversion, and AbortController support out of the box. If you still need Axios for interceptors or other features, an adapter is provided:
1import { client, axiosAdapter } from "laravel-precognition";2 3client.useHttpClient(axiosAdapter());
Pull request by @joetannenbaum
A brand new prompt for browsing, searching, and selecting from tabular data. Navigate with arrow keys, press / to search across all columns, or pass a filter closure for custom logic:
1$selected = datatable(2 label: 'Select a team member',3 headers: ['Name', 'Twitter', 'Role'],4 rows: [5 'taylor' => ['Taylor Otwell', '@taylorotwell', 'CEO'],6 'jess' => ['Jess Archer', '@jessarchercodes', 'Developer'],7 ],8);
Pull request by @joetannenbaum
Set and update the terminal window title at any point during execution:
1title('Deploying to Cloud...');2// ... work happens ...3title('Deployed!');
Pull request by @joetannenbaum
Stream text to the terminal with automatic word wrapping and a pleasant fade-in effect - perfect for displaying AI responses in real time:
1$stream = stream();2 3foreach ($events as $event) {4 $stream->append($event->delta);5}6 7$stream->close();
Pull request by @joetannenbaum
Display output from a running task with a spinner, real-time label updates, and scrollable log lines. Handles ANSI escape sequences and supports partial-line output for streaming.
1task('Installing dependencies', function (Logger $log) {2 Process::run(3 'composer install',4 fn ($type, $output) => $log->line($output)5 );6});
Pull request by @joetannenbaum
A new prompt that suggests matching values as the user types while still allowing free-form text input. Accepts a static list or a closure for dynamic suggestions.
1$key = autocomplete(2 label: 'New config key',3 options: collect(Arr::dot(config()->all()))->keys()->all(),4 placeholder: 'e.g. app.name, mail.from, database.default',5 required: true,6);
Pull request by @joetannenbaum
Select, multiselect, and search prompts now support a secondary info panel. Pass a string or closure to the new info parameter to show context about the currently highlighted item.
Pull request by @joetannenbaum
Send native desktop notifications straight from your CLI commands. Supports macOS (via osascript) and Linux (via notify-send):
1notify('Build complete', 'Deployed to production');2 3// With macOS-specific options4notify(5 title: 'Build complete',6 body: 'Deployed to production',7 sound: 'Glass',8);
Pull request by @joedixon
Reverb now supports per-application rate limiting, using Laravel's built-in rate limiter under the hood. Configure limits per app to protect your WebSocket server from abuse.
where($field, $operator, $value) on Builder ClassPull request by @gdebrauwer
Scout's query builder now accepts operators in where() clauses, making range queries straightforward without dropping into engine-specific callbacks:
1User::search('taylor')2 ->where('created_at', '>', now()->subMonth()->timestamp)3 ->get();
Pull request by @TitasGailius
Routes registered with Route::livewire() now link directly to the Livewire component. Clicking a route name navigates to the component file, and hovering shows the full component hover card.
Pull request by @TitasGailius
Intermediate translation keys like __('validation.attributes') now produce clickable links and hover info without false diagnostics. Previously only the deepest leaf keys were recognized.