{"id":86,"date":"2026-07-18T10:00:00","date_gmt":"2026-07-18T04:30:00","guid":{"rendered":"https:\/\/softcrony.com\/blog\/?p=86"},"modified":"2026-07-18T10:00:00","modified_gmt":"2026-07-18T04:30:00","slug":"laravel-13-new-features-2026","status":"publish","type":"post","link":"https:\/\/softcrony.com\/blog\/laravel-13-new-features-2026\/","title":{"rendered":"Laravel 13: Every New Feature Explained with Code Examples (2026)"},"content":{"rendered":"<p>Laravel 13 was released March 17, 2026, announced live by Taylor Otwell at Laracon EU 2026. The headline promise was zero breaking changes \u2014 and it delivered. This is one of the most developer-friendly major releases in Laravel&#8217;s history.<\/p>\n<p>This guide covers every confirmed new feature with before\/after code examples, the requirements, the support timeline, and a step-by-step upgrade guide from Laravel 12.<\/p>\n<h2>Requirements<\/h2>\n<table>\n<thead>\n<tr>\n<th>Requirement<\/th>\n<th>Laravel 12<\/th>\n<th>Laravel 13<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>PHP Minimum<\/td>\n<td>8.2<\/td>\n<td><strong>8.3<\/strong><\/td>\n<\/tr>\n<tr>\n<td>PHP Maximum<\/td>\n<td>8.5<\/td>\n<td>8.5<\/td>\n<\/tr>\n<tr>\n<td>MySQL<\/td>\n<td>8.0+<\/td>\n<td>8.0+<\/td>\n<\/tr>\n<tr>\n<td>MariaDB<\/td>\n<td>10.6+<\/td>\n<td>10.6+<\/td>\n<\/tr>\n<tr>\n<td>SQLite<\/td>\n<td>3.35+<\/td>\n<td>3.35+<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>The only infrastructure change:<\/strong> PHP 8.3 is now the minimum. If your server runs PHP 8.2, upgrade PHP before upgrading Laravel. Everything else is application-level and non-breaking.<\/p>\n<h2>Support Timeline<\/h2>\n<table>\n<thead>\n<tr>\n<th>Version<\/th>\n<th>Release<\/th>\n<th>Bug Fixes Until<\/th>\n<th>Security Fixes Until<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Laravel 11<\/td>\n<td>Mar 12, 2024<\/td>\n<td>Sep 3, 2025<\/td>\n<td>Mar 12, 2026<\/td>\n<\/tr>\n<tr>\n<td>Laravel 12<\/td>\n<td>Feb 24, 2025<\/td>\n<td>Aug 13, 2026<\/td>\n<td>Feb 24, 2027<\/td>\n<\/tr>\n<tr>\n<td><strong>Laravel 13<\/strong><\/td>\n<td><strong>Mar 17, 2026<\/strong><\/td>\n<td><strong>Q3 2027<\/strong><\/td>\n<td><strong>Q1 2028<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Laravel 12 is fully supported until February 2027 \u2014 no emergency to upgrade. For new projects, start on Laravel 13 today.<\/p>\n<h2>Feature 1 \u2014 PHP Attributes for Everything<\/h2>\n<p>The biggest quality-of-life improvement in Laravel 13. PHP 8 Attributes are now an alternative to class properties for configuring Laravel components. This is a non-breaking change \u2014 existing property-based configuration continues to work.<\/p>\n<h3>Eloquent Models<\/h3>\n<p>Before (Laravel 12):<\/p>\n<pre><code>&lt;?php\r\n\r\nnamespace App\\Models;\r\n\r\nuse Illuminate\\Database\\Eloquent\\Model;\r\n\r\nclass User extends Model\r\n{\r\n    protected $table = 'users';\r\n    protected $primaryKey = 'user_id';\r\n    protected $keyType = 'string';\r\n    public $incrementing = false;\r\n\r\n    protected $hidden = ['password', 'remember_token'];\r\n\r\n    protected $fillable = [\r\n        'name',\r\n        'email',\r\n        'phone',\r\n        'company_id',\r\n    ];\r\n}<\/code><\/pre>\n<p>After (Laravel 13):<\/p>\n<pre><code>&lt;?php\r\n\r\nnamespace App\\Models;\r\n\r\nuse Illuminate\\Database\\Eloquent\\Attributes\\Table;\r\nuse Illuminate\\Database\\Eloquent\\Attributes\\Hidden;\r\nuse Illuminate\\Database\\Eloquent\\Attributes\\Fillable;\r\nuse Illuminate\\Database\\Eloquent\\Model;\r\n\r\n#[Table('users', key: 'user_id', keyType: 'string', incrementing: false)]\r\n#[Hidden(['password', 'remember_token'])]\r\n#[Fillable(['name', 'email', 'phone', 'company_id'])]\r\nclass User extends Model\r\n{\r\n    \/\/ Clean \u2014 no property clutter\r\n}<\/code><\/pre>\n<p>All available model attributes:<\/p>\n<pre><code>#[Appends(['full_name', 'avatar_url'])]\r\n#[Connection('mysql_readonly')]\r\n#[Fillable(['name', 'email'])]\r\n#[Guarded(['id', 'created_at'])]\r\n#[Hidden(['password'])]\r\n#[Table('users', key: 'user_id')]\r\n#[Touches(['profile', 'posts'])]\r\n#[Unguarded]\r\n#[Visible(['name', 'email'])]<\/code><\/pre>\n<h3>Queue Jobs<\/h3>\n<p>Before (Laravel 12):<\/p>\n<pre><code>class ProcessPodcast implements ShouldQueue\r\n{\r\n    public $connection = 'redis';\r\n    public $queue = 'podcasts';\r\n    public $tries = 3;\r\n    public $timeout = 120;\r\n    public $backoff = [1, 5, 10];\r\n}<\/code><\/pre>\n<p>After (Laravel 13):<\/p>\n<pre><code>use Illuminate\\Queue\\Attributes\\Connection;\r\nuse Illuminate\\Queue\\Attributes\\Queue;\r\nuse Illuminate\\Queue\\Attributes\\Tries;\r\nuse Illuminate\\Queue\\Attributes\\Timeout;\r\nuse Illuminate\\Queue\\Attributes\\Backoff;\r\n\r\n#[Connection('redis')]\r\n#[Queue('podcasts')]\r\n#[Tries(3)]\r\n#[Timeout(120)]\r\n#[Backoff([1, 5, 10])]\r\nclass ProcessPodcast implements ShouldQueue\r\n{\r\n    \/\/ No property clutter\r\n}<\/code><\/pre>\n<p>All available queue attributes:<\/p>\n<pre><code>#[Backoff([1, 5, 10])]\r\n#[Connection('redis')]\r\n#[FailOnTimeout]\r\n#[MaxExceptions(3)]\r\n#[Queue('podcasts')]\r\n#[Timeout(120)]\r\n#[Tries(3)]\r\n#[UniqueFor(3600)]<\/code><\/pre>\n<h3>Console Commands<\/h3>\n<p>Before (Laravel 12):<\/p>\n<pre><code>class SendMailCommand extends Command\r\n{\r\n    protected $signature = 'mail:send {user} {--queue}';\r\n    protected $description = 'Send a marketing email to a user';\r\n}<\/code><\/pre>\n<p>After (Laravel 13):<\/p>\n<pre><code>use Illuminate\\Console\\Attributes\\Signature;\r\nuse Illuminate\\Console\\Attributes\\Description;\r\n\r\n#[Signature('mail:send {user} {--queue}')]\r\n#[Description('Send a marketing email to a user')]\r\nclass SendMailCommand extends Command\r\n{\r\n    \/\/ Signature and description live at the top, not buried in properties\r\n}<\/code><\/pre>\n<h3>Form Requests<\/h3>\n<pre><code>#[RedirectTo('\/dashboard')]\r\n#[StopOnFirstFailure]\r\nclass CreateOrderRequest extends FormRequest\r\n{\r\n    public function rules(): array\r\n    {\r\n        return [\r\n            'product_id' =&gt; 'required|exists:products,id',\r\n            'quantity'   =&gt; 'required|integer|min:1',\r\n        ];\r\n    }\r\n}<\/code><\/pre>\n<h3>API Resources<\/h3>\n<pre><code>#[Collects(OrderResource::class)]\r\n#[PreserveKeys]\r\nclass OrderCollection extends ResourceCollection {}\r\n<\/code><\/pre>\n<p>Attributes also work on Listeners, Notifications, Mailables, Broadcast Events, Factories, and Test Seeders \u2014 the full framework is covered.<\/p>\n<h2>Feature 2 \u2014 Cache::touch()<\/h2>\n<p>A small but frequently needed feature. The new <code>Cache::touch()<\/code> method extends a cached item&#8217;s TTL without fetching or re-storing the value.<\/p>\n<p>Before (Laravel 12 \u2014 required a get + put):<\/p>\n<pre><code>\/\/ Old way \u2014 fetches the value unnecessarily\r\n$value = Cache::get('user_session:123');\r\nif ($value !== null) {\r\n    Cache::put('user_session:123', $value, 3600); \/\/ Re-stores unnecessarily\r\n}<\/code><\/pre>\n<p>After (Laravel 13):<\/p>\n<pre><code>\/\/ Just extend the TTL \u2014 no get, no re-store\r\nCache::touch('user_session:123', 3600);\r\n\r\n\/\/ With a DateTime\r\nCache::touch('analytics_data', now()->addHours(6));\r\n\r\n\/\/ Extend indefinitely (remove expiry)\r\nCache::touch('permanent_cache', null);\r\n\r\n\/\/ Returns true if key exists, false if not\r\n$extended = Cache::touch('user_session:123', 3600);\r\nif (!$extended) {\r\n    \/\/ Key expired before we could touch it \u2014 re-create it\r\n}<\/code><\/pre>\n<p>This is implemented across all cache drivers: Array, APC, Database, DynamoDB, File, Memcached, Memoized, Null, and Redis. Redis uses a single EXPIRE command, Memcached uses TOUCH, and the database driver issues a single UPDATE.<\/p>\n<p>Perfect for session extension, sliding cache windows, and keeping computed results alive while they&#8217;re being used.<\/p>\n<h2>Feature 3 \u2014 Laravel AI SDK (Stable)<\/h2>\n<p>The headline feature in the release notes is the new Laravel AI SDK. Previously in beta, it went production-stable with Laravel 13.<\/p>\n<p>The AI SDK gives Laravel a first-party, provider-agnostic way to integrate AI \u2014 supporting Claude (Anthropic), OpenAI, and Gemini from a single unified API:<\/p>\n<pre><code>composer require laravel\/ai<\/code><\/pre>\n<pre><code>\/\/ config\/ai.php\r\nreturn [\r\n    'default' =&gt; env('AI_PROVIDER', 'anthropic'),\r\n\r\n    'providers' =&gt; [\r\n        'anthropic' =&gt; [\r\n            'api_key' =&gt; env('ANTHROPIC_API_KEY'),\r\n            'model'   =&gt; env('ANTHROPIC_MODEL', 'claude-sonnet-4-5'),\r\n        ],\r\n        'openai' =&gt; [\r\n            'api_key' =&gt; env('OPENAI_API_KEY'),\r\n            'model'   =&gt; env('OPENAI_MODEL', 'gpt-4o'),\r\n        ],\r\n    ],\r\n];<\/code><\/pre>\n<pre><code>use Laravel\\AI\\Facades\\AI;\r\n\r\n\/\/ Simple completion\r\n$response = AI::complete('Summarize this text: ' . $text);\r\n\r\n\/\/ Chat with history\r\n$response = AI::chat([\r\n    ['role' =&gt; 'system', 'content' =&gt; 'You are a helpful assistant.'],\r\n    ['role' =&gt; 'user', 'content' =&gt; 'What is Laravel?'],\r\n]);\r\n\r\n\/\/ Stream response\r\nAI::stream('Write a product description for: ' . $product->name,\r\n    function (string $chunk) {\r\n        echo $chunk;\r\n    }\r\n);\r\n\r\n\/\/ Switch provider on the fly\r\nAI::provider('openai')->complete('Hello');\r\nAI::provider('anthropic')->complete('Hello');<\/code><\/pre>\n<p>The SDK handles token counting, retry logic, streaming, and provider switching \u2014 without locking you to a specific AI company&#8217;s SDK.<\/p>\n<h2>Feature 4 \u2014 Passkey Authentication<\/h2>\n<p>Laravel 13 ships with first-party Passkey support \u2014 the WebAuthn-based authentication standard that replaces passwords with device biometrics (Face ID, fingerprint, Windows Hello).<\/p>\n<pre><code>composer require laravel\/passkeys<\/code><\/pre>\n<pre><code>php artisan passkeys:install<\/code><\/pre>\n<pre><code>\/\/ Register a passkey\r\nuse Laravel\\Passkeys\\Facades\\Passkeys;\r\n\r\n\/\/ In your registration controller\r\npublic function startRegistration(Request $request)\r\n{\r\n    $options = Passkeys::generateRegistrationOptions($request->user());\r\n    return response()->json($options);\r\n}\r\n\r\npublic function finishRegistration(Request $request)\r\n{\r\n    $passkey = Passkeys::verifyRegistration(\r\n        $request->user(),\r\n        $request->all()\r\n    );\r\n\r\n    return response()->json(['passkey_id' =&gt; $passkey->id]);\r\n}\r\n\r\n\/\/ Authenticate with passkey\r\npublic function startAuthentication(Request $request)\r\n{\r\n    $options = Passkeys::generateAuthenticationOptions();\r\n    return response()->json($options);\r\n}\r\n\r\npublic function finishAuthentication(Request $request)\r\n{\r\n    $user = Passkeys::verifyAuthentication($request->all());\r\n    Auth::login($user);\r\n\r\n    return redirect('\/dashboard');\r\n}<\/code><\/pre>\n<p>Frontend integration uses the WebAuthn browser API \u2014 compatible with all modern browsers and devices with biometric sensors. No passwords stored, no password reset flows, no phishing risk.<\/p>\n<h2>Feature 5 \u2014 Queue::route()<\/h2>\n<p>The new <code>Queue::route()<\/code> method lets you define which queue and connection each job class uses from a single location in a service provider. Previously, teams either set queue properties on each job class or repeated the configuration at every dispatch site.<\/p>\n<pre><code>\/\/ Before \u2014 repeated at every dispatch\r\nProcessPodcast::dispatch($podcast)->onQueue('podcasts')->onConnection('redis');\r\nSendWelcomeEmail::dispatch($user)->onQueue('emails')->onConnection('sqs');\r\nGenerateReport::dispatch($report)->onQueue('reports')->onConnection('redis');\r\n\r\n\/\/ After \u2014 define once in AppServiceProvider\r\nuse Illuminate\\Support\\Facades\\Queue;\r\n\r\nQueue::route([\r\n    ProcessPodcast::class  =&gt; 'redis:podcasts',\r\n    SendWelcomeEmail::class =&gt; 'sqs:emails',\r\n    GenerateReport::class  =&gt; 'redis:reports',\r\n]);\r\n\r\n\/\/ Now just dispatch \u2014 routing is automatic\r\nProcessPodcast::dispatch($podcast);\r\nSendWelcomeEmail::dispatch($user);\r\nGenerateReport::dispatch($report);<\/code><\/pre>\n<p>Combined with the new PHP Attributes for queue configuration, this is the cleanest queue setup Laravel has ever had.<\/p>\n<h2>Feature 6 \u2014 JSON:API Support<\/h2>\n<p>Laravel 13 includes first-party support for the JSON:API specification. The new resource classes handle response object serialization, relationship inclusion, sparse fieldsets, links and compliant response headers automatically.<\/p>\n<pre><code>php artisan make:json-api-resource PostResource<\/code><\/pre>\n<pre><code>use Illuminate\\Http\\Resources\\Json\\JsonApiResource;\r\n\r\nclass PostResource extends JsonApiResource\r\n{\r\n    public function toAttributes(Request $request): array\r\n    {\r\n        return [\r\n            'title'      =&gt; $this-&gt;title,\r\n            'content'    =&gt; $this-&gt;content,\r\n            'published'  =&gt; $this-&gt;published_at?-&gt;toISOString(),\r\n        ];\r\n    }\r\n\r\n    public function toRelationships(Request $request): array\r\n    {\r\n        return [\r\n            'author'   =&gt; AuthorResource::make($this-&gt;author),\r\n            'comments' =&gt; CommentResource::collection($this-&gt;comments),\r\n        ];\r\n    }\r\n\r\n    public function toLinks(Request $request): array\r\n    {\r\n        return [\r\n            'self' =&gt; route('posts.show', $this-&gt;id),\r\n        ];\r\n    }\r\n}<\/code><\/pre>\n<p>Response automatically follows JSON:API spec:<\/p>\n<pre><code>{\r\n  \"data\": {\r\n    \"type\": \"posts\",\r\n    \"id\": \"1\",\r\n    \"attributes\": {\r\n      \"title\": \"Laravel 13 Released\",\r\n      \"content\": \"...\",\r\n      \"published\": \"2026-03-17T09:00:00Z\"\r\n    },\r\n    \"relationships\": {\r\n      \"author\": {\r\n        \"data\": { \"type\": \"users\", \"id\": \"42\" }\r\n      }\r\n    },\r\n    \"links\": {\r\n      \"self\": \"https:\/\/api.example.com\/posts\/1\"\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<h2>Feature 7 \u2014 Typed Configuration<\/h2>\n<p>No more guessing whether a config value is a string, boolean, or integer:<\/p>\n<pre><code>\/\/ Before \u2014 could return string \"true\" or boolean true depending on env\r\n$debug = config('app.debug'); \/\/ What type is this?\r\n\r\n\/\/ Laravel 13 \u2014 typed retrieval\r\n$debug = config()->boolean('app.debug');     \/\/ Always bool\r\n$port  = config()->integer('database.port'); \/\/ Always int\r\n$name  = config()->string('app.name');       \/\/ Always string\r\n$hosts = config()->array('cache.stores');    \/\/ Always array\r\n\r\n\/\/ Throws ConfigTypeMismatchException if type doesn't match\r\n\/\/ Catches a whole class of bugs at boot time<\/code><\/pre>\n<h2>Feature 8 \u2014 Middleware Simplification<\/h2>\n<p>Laravel 13 simplifies the middleware stack. The <code>app\/Http\/Kernel.php<\/code> file is gone (deprecated since Laravel 11, now removed). All middleware configuration lives in <code>bootstrap\/app.php<\/code>.<\/p>\n<pre><code>\/\/ bootstrap\/app.php \u2014 everything in one place\r\nreturn Application::configure(basePath: dirname(__DIR__))\r\n    ->withRouting(\r\n        web: __DIR__.'\/..\/routes\/web.php',\r\n        api: __DIR__.'\/..\/routes\/api.php',\r\n    )\r\n    ->withMiddleware(function (Middleware $middleware) {\r\n        \/\/ Global middleware\r\n        $middleware->append(ForceHttps::class);\r\n\r\n        \/\/ Route group middleware\r\n        $middleware->api(append: [\r\n            EnsureApiToken::class,\r\n        ]);\r\n\r\n        \/\/ Middleware aliases\r\n        $middleware->alias([\r\n            'verified' =&gt; EnsureEmailIsVerified::class,\r\n        ]);\r\n    })\r\n    ->create();<\/code><\/pre>\n<h2>Feature 9 \u2014 Reverb Database Driver<\/h2>\n<p>Laravel Reverb (the WebSocket server) now includes a database driver \u2014 meaning you can run real-time WebSockets without Redis for smaller applications:<\/p>\n<pre><code># .env \u2014 use database instead of Redis for WebSocket state\r\nREVERB_DRIVER=database\r\n\r\n# No Redis required for:\r\n# - Channel presence tracking\r\n# - Connection state\r\n# - Message queuing (small scale)<\/code><\/pre>\n<p>For production at scale, Redis remains the recommended driver. The database driver is ideal for development environments and small-scale deployments where Redis is overkill.<\/p>\n<h2>Feature 10 \u2014 route:conflicts Command<\/h2>\n<p>The <code>route:conflicts<\/code> command detects overlapping routes \u2014 a common source of hard-to-debug bugs:<\/p>\n<pre><code>php artisan route:conflicts<\/code><\/pre>\n<pre><code>+-------------------+--------+---------------------------+\r\n| URI               | Method | Conflict                  |\r\n+-------------------+--------+---------------------------+\r\n| \/users\/{id}       | GET    | Overlaps with \/users\/new  |\r\n| \/products\/{slug}  | GET    | Overlaps with \/products\/1 |\r\n+-------------------+--------+---------------------------+<\/code><\/pre>\n<h2>PHP 8.3 \u2014 What You Actually Gain<\/h2>\n<p>Upgrading to PHP 8.3 for Laravel 13 isn&#8217;t just a requirement \u2014 it brings real improvements:<\/p>\n<pre><code>\/\/ Typed class constants (PHP 8.3)\r\nclass Status\r\n{\r\n    const string ACTIVE   = 'active';\r\n    const string INACTIVE = 'inactive';\r\n    const int    MAX_RETRY = 3;\r\n}\r\n\r\n\/\/ json_validate() \u2014 no more json_decode() just to check validity\r\n$valid = json_validate($jsonString); \/\/ true or false, no decode needed\r\n\r\n\/\/ Readonly property improvements\r\nclass Order\r\n{\r\n    public function __construct(\r\n        public readonly string $id,\r\n        public readonly float  $total,\r\n    ) {}\r\n}\r\n\r\n\/\/ Dynamic class constant fetch\r\n$constant = Status::{$name}; \/\/ Valid in PHP 8.3<\/code><\/pre>\n<h2>Laravel 12 vs Laravel 13 \u2014 Side by Side<\/h2>\n<table>\n<thead>\n<tr>\n<th>Feature<\/th>\n<th>Laravel 12<\/th>\n<th>Laravel 13<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>PHP minimum<\/td>\n<td>8.2<\/td>\n<td>8.3<\/td>\n<\/tr>\n<tr>\n<td>Model configuration<\/td>\n<td>Class properties<\/td>\n<td>PHP Attributes (optional)<\/td>\n<\/tr>\n<tr>\n<td>Job configuration<\/td>\n<td>Class properties<\/td>\n<td>PHP Attributes (optional)<\/td>\n<\/tr>\n<tr>\n<td>Command signature<\/td>\n<td>Class property<\/td>\n<td>PHP Attribute (optional)<\/td>\n<\/tr>\n<tr>\n<td>Cache TTL extension<\/td>\n<td>get + put<\/td>\n<td>Cache::touch()<\/td>\n<\/tr>\n<tr>\n<td>AI integration<\/td>\n<td>Third-party packages<\/td>\n<td>First-party Laravel AI SDK<\/td>\n<\/tr>\n<tr>\n<td>Passkeys<\/td>\n<td>Third-party only<\/td>\n<td>First-party support<\/td>\n<\/tr>\n<tr>\n<td>Queue routing<\/td>\n<td>Per-dispatch<\/td>\n<td>Queue::route() central config<\/td>\n<\/tr>\n<tr>\n<td>JSON:API<\/td>\n<td>Third-party<\/td>\n<td>First-party resources<\/td>\n<\/tr>\n<tr>\n<td>Config types<\/td>\n<td>Untyped<\/td>\n<td>Typed retrieval<\/td>\n<\/tr>\n<tr>\n<td>Middleware config<\/td>\n<td>Kernel.php (legacy)<\/td>\n<td>bootstrap\/app.php only<\/td>\n<\/tr>\n<tr>\n<td>WebSockets (Reverb)<\/td>\n<td>Redis only<\/td>\n<td>Redis + Database driver<\/td>\n<\/tr>\n<tr>\n<td>Route conflicts<\/td>\n<td>Manual detection<\/td>\n<td>route:conflicts command<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>How to Upgrade from Laravel 12 to Laravel 13<\/h2>\n<p>Most applications upgrade in under 10 minutes. Here&#8217;s the process:<\/p>\n<h3>Step 1 \u2014 Check PHP Version<\/h3>\n<pre><code>php -v\r\n# Must show PHP 8.3.x or higher\r\n# If not, upgrade PHP in your hosting panel (Hostinger\/cPanel: PHP Configuration)<\/code><\/pre>\n<h3>Step 2 \u2014 Check Package Compatibility<\/h3>\n<pre><code># Check which packages need updates\r\ncomposer outdated\r\n\r\n# Key packages to verify:\r\n# - livewire\/livewire\r\n# - inertiajs\/inertia-laravel\r\n# - filament\/filament\r\n# - spatie\/* packages\r\n# - laravel\/sanctum\r\n# - laravel\/horizon<\/code><\/pre>\n<p>Most major packages \u2014 Livewire, Inertia, Filament, Spatie \u2014 already have Laravel 13 support. Check each package&#8217;s GitHub releases page.<\/p>\n<h3>Step 3 \u2014 Update composer.json<\/h3>\n<pre><code>{\r\n    \"require\": {\r\n        \"php\": \"^8.3\",\r\n        \"laravel\/framework\": \"^13.0\"\r\n    }\r\n}<\/code><\/pre>\n<h3>Step 4 \u2014 Run Composer Update<\/h3>\n<pre><code>composer update laravel\/framework --with-dependencies<\/code><\/pre>\n<h3>Step 5 \u2014 Run the Upgrade Command<\/h3>\n<pre><code>php artisan upgrade<\/code><\/pre>\n<p>Laravel 13 includes an upgrade command that checks for common issues and guides you through any manual changes needed.<\/p>\n<h3>Step 6 \u2014 Clear and Test<\/h3>\n<pre><code>php artisan optimize:clear\r\nphp artisan test\r\nphp artisan route:conflicts<\/code><\/pre>\n<h3>Step 7 \u2014 Use Laravel Shift (Alternative)<\/h3>\n<p>For complex applications, Laravel Shift automates the upgrade \u2014 it opens a PR with atomic commits covering every change. Worth the small fee for large codebases.<\/p>\n<h2>Should You Upgrade Now?<\/h2>\n<p><strong>New projects:<\/strong> Yes \u2014 always start new projects on the latest version. Laravel 13 is the current stable release.<\/p>\n<p><strong>Existing projects on Laravel 12:<\/strong> No emergency \u2014 Laravel 12 gets bug fixes until August 2026 and security fixes until February 2027. Plan the upgrade for your next maintenance window.<\/p>\n<p><strong>Existing projects on Laravel 11 or older:<\/strong> Upgrade now. Laravel 11&#8217;s security support ended March 2026.<\/p>\n<p><strong>The real reason to upgrade:<\/strong> PHP Attributes alone reduce boilerplate significantly. The Laravel AI SDK stable means AI integration is now a first-party, supported part of the framework. Queue::route() cleans up dispatch sites across large codebases. These are genuine improvements worth having.<\/p>\n<p>If you need help upgrading a Laravel application to version 13, or want a new project built on the latest stack, <a href=\"https:\/\/softcrony.com\/contact\/\">our team at Softcrony is happy to help<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Laravel 13 was released March 17, 2026, announced live by Taylor Otwell at Laracon EU 2026. The headline promise was zero breaking changes \u2014 and it delivered. This is one of the most developer-friendly major releases in Laravel&#8217;s history. This guide covers every confirmed new feature with before\/after code examples, the requirements, the support timeline, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":89,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[90,19,88,30,89,18],"class_list":["post-86","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-framework","tag-laravel","tag-laravel-13","tag-php","tag-php-8-3","tag-web-development"],"_links":{"self":[{"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/posts\/86","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/comments?post=86"}],"version-history":[{"count":2,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/posts\/86\/revisions"}],"predecessor-version":[{"id":88,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/posts\/86\/revisions\/88"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/media\/89"}],"wp:attachment":[{"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/media?parent=86"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/categories?post=86"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/softcrony.com\/blog\/wp-json\/wp\/v2\/tags?post=86"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}