Key takeaways
- All three maintained Filament lines run on Laravel 13 once you’re on a recent minor: v5 and v4 from spring 2026, and v3 from 3.3.54 (June 2026).
- Laravel 13 needs PHP 8.3 or newer. Filament itself still accepts PHP 8.2, so PHP is usually the real blocker.
- Watch for the quiet changes: new session cookie and cache prefix names (everyone is logged out and the cache starts empty),
serializable_classesdefaulting tofalse, and domain routes now taking priority over non-domain routes. - Update your plugins as well. Many dropped Laravel 11 or require newer PHP when they added Laravel 13 support.
Laravel 13 was released on 17 March 2026. Its own upgrade guide estimates about ten minutes for a typical app. A Filament panel adds a few moving parts: the Filament version, plugins, Livewire, and admin users who don’t like being logged out on a Tuesday afternoon. Here’s a checklist you can work through in order.
1. Pick a Filament version that supports Laravel 13
| Filament line | Laravel 13 support | Notes |
|---|---|---|
| 5.x | Yes, since the 5.4 release (March 2026) | Current: 5.8.4. illuminate/contracts: ^11.28|^12.0|^13.0 |
| 4.x | Yes, on recent 4.x releases | Current: 4.13.4, same Laravel range, Livewire ^3.7 |
| 3.x | Yes, since 3.3.54 (12 June 2026) | Security fixes only now. Bug fixes ended 1 Aug 2026 |
In practice, move to the latest minor of whichever line you’re on before bumping Laravel:
composer update "filament/*" -W
composer show filament/filament # confirm the versionIf you’re on the early 5.0–5.3 releases, Composer will refuse Laravel 13. That’s the “Can’t install Filament v5 on Laravel 13” error people reported in March 2026. The fix is simply to update Filament.
2. Upgrade PHP to 8.3 or newer
| Laravel | PHP support | Bug fixes until | Security fixes until |
|---|---|---|---|
| 12 | 8.2–8.5 | 13 Aug 2026 | 24 Feb 2027 |
| 13 | 8.3–8.5 | Q3 2027 | 17 Mar 2028 |
Source: Laravel release notes.
Upgrade PHP first and deploy that on its own. Then upgrade Laravel. For the full reasoning, see our explainer Can you run Laravel 13 on PHP 8.2? Our Laravel PHP version compatibility tool shows the whole matrix.
Some Laravel 13-era packages go further than 8.3. For example, spatie/laravel-activitylog v5 and spatie/laravel-permission v7 require PHP 8.4. Current laravel-permission v8 requires 8.3. Check before you choose your PHP version.
3. Update composer.json
The core Laravel constraint changes from the upgrade guide:
{
"require": {
"php": "^8.3",
"laravel/framework": "^13.0",
"laravel/tinker": "^3.0",
"filament/filament": "^5.0"
},
"require-dev": {
"laravel/boost": "^2.0",
"phpunit/phpunit": "^12.0",
"pestphp/pest": "^4.0"
}
}Then:
composer update -WIf Composer fails, composer why-not laravel/framework 13.0 shows which package is blocking the upgrade. Our Composer semver constraint checker helps you read constraints like ^11.28|^12.0|^13.0.
4. Audit your Filament plugins
Many plugins released Laravel 13 support at the same time as dropping older versions. Some examples from Packagist in September 2026:
- Filament Shield 4.3.x:
illuminate/* ^11.28|^12.0|^13.0andspatie/laravel-permission ^6.0|^7.0|^8.0 - Filament Spatie Backup 4.x: Laravel 12–13. Laravel 13 with Spatie Backup 10 needs PHP newer than 8.2
- Badgeable Column 4.1: added Laravel 13 and dropped Laravel 11
Run composer outdated "*filament*" and read each plugin’s release notes for “Laravel 13”.
5. Handle the Laravel 13 changes that affect admin panels
Most of the upgrade guide won’t touch a Filament app. These items will.
CSRF middleware renamed to PreventRequestForgery
VerifyCsrfToken is now PreventRequestForgery. It adds origin checks using the Sec-Fetch-Site header. The old class names remain as deprecated aliases, so nothing breaks today. Update explicit references anyway:
// bootstrap/app.php (Laravel 13 style)
->withMiddleware(function (Middleware $middleware): void {
$middleware->preventRequestForgery(except: [
'stripe/*', // e.g. Cashier webhooks
]);
})Filament and Livewire requests carry the CSRF token as normal and need no exclusions. If you run the panel behind an unusual proxy or embed it in an iframe on another origin, test logins and form submissions after deploying.
Session cookie and cache prefix names changed
Laravel 13’s default names use hyphens instead of underscores (laravel-session, laravel-cache-). If you never set these explicitly:
- All admins are logged out when the cookie name changes.
- Your cache starts empty under the new prefix. Cached dashboard stats get recomputed at once, so expect a load spike on the first dashboard hits.
To keep the old names, set them explicitly before you deploy:
# Laravel 12 derived these from APP_NAME (slugged with underscores).
# Use the values your production app actually has today.
SESSION_COOKIE=myapp_session
CACHE_PREFIX=myapp_cache_
REDIS_PREFIX=myapp_database_To find the real values, run php artisan tinker --execute="dump(config('session.cookie'), config('cache.prefix'), config('database.redis.options.prefix'));" on the current production release before upgrading.
Session serialisation now defaults to JSON
The default for session serialisation changes from php to json, which is safer but invalidates active sessions. Keep php if you can’t afford a logout, or combine this change with the cookie rename and log everyone out once.
serializable_classes in the cache config defaults to false
This is a security hardening: PHP objects are no longer unserialised from the cache unless you allow-list them. Filament apps often cache objects without realising it, for example a widget caching a Collection of Eloquent models:
// Before: cached a Collection of models, which is now blocked by default
$top = Cache::remember('dashboard.top-customers', 300, fn () => Customer::top(10)->get());
// Better: cache plain arrays
$top = Cache::remember('dashboard.top-customers', 300,
fn () => Customer::top(10)->get(['id', 'name', 'lifetime_value'])->toArray());Alternatively, list the classes you intend to cache in config/cache.php under serializable_classes.
Domain routes now take priority
Laravel 13 matches domain routes before non-domain routes. That matters if you use ->domain() on a panel or ->tenantDomain('{tenant:slug}.example.com') for multi-tenant panels. After upgrading, run php artisan route:list --path=admin and test tenant URLs, the marketing site, and any catch-all routes.
Eloquent: no model instantiation inside boot
Laravel 13 throws a LogicException if a model is instantiated inside another model’s boot or booted method. Old observers and traits sometimes do this, for example static::creating(fn () => new AuditEntry(...)) in the wrong place. Run your create and edit tests.
Polymorphic pivot table names are pluralised
If you have custom morph pivot models without an explicit $table, Laravel 13 may now look for a pluralised name. Set protected $table = '...'; on those pivot models. The Spatie permission and tags tables are configured explicitly, so they’re unaffected.
Smaller changes that show up in tests
Strfactories reset between tests, so custom UUID/ULID factories must be set in each test’s setup.Js::from()no longer escapes Unicode (\u00e8becomesè), which affects snapshot-style assertions.upsert()on MySQL/MariaDB throws on an emptyuniqueBy. Check custom importers.- The
JobAttemptedevent exposes$exceptioninstead of$exceptionOccurred. Listeners that watch Filament import and export jobs need updating. pagination::defaultis nowpagination::bootstrap-3. This only matters if you render Laravel’s paginator views yourself.
6. Static analysis: DB::raw() is stricter
Laravel 13 narrowed the types of Connection::raw() and orderByRaw() to literal strings. Your code still runs, but Larastan will flag interpolated SQL like this, which often turns up in table modifyQueryUsing() callbacks:
// Flagged: interpolated raw SQL
->modifyQueryUsing(fn ($q) => $q->orderByRaw("FIELD(status, {$order})"))
// Better: bindings
->modifyQueryUsing(fn ($q) => $q->orderByRaw('FIELD(status, ?, ?, ?)', ['open', 'pending', 'closed']))Treat these warnings as security fixes rather than noise.
7. Verify
php artisan optimize:clear
php artisan filament:optimize
php artisan about # Laravel, PHP and driver versions at a glance
php artisan test --parallelThen run a manual smoke test: log in, switch tenants, run a search, filter and sort, create and edit a record with file uploads, and trigger an import or export if you use them (these exercise queue batches and notifications).
If you use Laravel Boost, Boost 2.0 adds an /upgrade-laravel-v13 command for supported agents. It’s a useful first pass, but review what it changes.
FAQ
Does Filament v5 support Laravel 13?
Yes. Current 5.x releases accept ^11.28|^12.0|^13.0. If Composer refuses, update Filament to the latest 5.x minor, because early 5.0–5.3 releases predate Laravel 13 support.
Does Filament v3 work with Laravel 13?
Yes, from v3.3.54 (June 2026). But v3 no longer gets bug fixes, so pairing a brand-new framework with an unmaintained admin version is a short-term fix at best.
Why were all my Filament users logged out after upgrading?
Laravel 13 changed the default session cookie name and the session serialisation format. Set SESSION_COOKIE (and keep php serialisation) before deploying if you want to keep existing sessions.
What PHP version do I need for Filament on Laravel 13?
PHP 8.3 or newer, because of Laravel 13. Some plugins and Spatie packages need 8.4.
Sources and further reading
- Laravel 13 release notes and support policy
- Laravel 13 upgrade guide
- Filament v3.3.54 release (Laravel 13 support)
- filament/support on Packagist
- What We Know About Laravel 13 (Laravel News)
Related on The Web Tier: Filament v4 to v5 upgrade guide · Can you run Laravel 13 on PHP 8.2?
