Back to Blog
DevelopmentFeb 8, 202614 min read

How to Upgrade Filament 3 to Filament 4 in Laravel

How to Upgrade Filament 3 to Filament 4 in Laravel
ST
SynchSoft Team
SynchSoft Team

Introduction

Filament 4 is here, and if you're running a Laravel admin panel on Filament v3.3, upgrading brings a new Schema architecture, Tailwind CSS v4 support, and significant API improvements. We recently upgraded a production co-parenting app from Filament v3.3.45 to Filament v4.7.0 on Laravel 11, and this guide walks through every step — including the gotchas the official docs don't warn you about.

This guide covers the exact commands we ran, the errors we hit, and the manual fixes required after the automated Rector tool missed several breaking changes. If you've searched for "filament v4 migration guide", "filament 4 breaking changes", or "how to upgrade filament 3 to 4" — you're in the right place.

Prerequisites

Before starting, make sure you have:

RequirementMinimum Version
PHP8.2+
Laravel11.x
Filament3.x (we started on 3.3.45)
Composer2.x
GitAny recent version

Important: Commit all your changes before running the upgrade. The Rector tool modifies files directly. You need a clean working tree to safely rollback if something goes wrong.

git add -A && git commit -m "chore: pre-filament-v4-upgrade snapshot"

We recommend creating a dedicated branch:

git checkout -b upgrade/filament-v4

Step 1: Install the Filament Upgrade Tool

Filament ships an automated upgrade package that uses Rector to handle most breaking changes across your codebase.

composer require filament/upgrade:"^4.0" -W --dev

This installs three dev dependencies:

  • filament/upgrade (v4.7.0)
  • phpstan/phpstan
  • rector/rector

Step 2: Run the Automated Filament v4 Upgrade (Rector)

The upgrade tool scans your Filament code and applies transformations automatically:

vendor/bin/filament-v4

Fix: "MissingInputException: Aborted" Error

If you're running this in a non-interactive terminal (CI/CD, scripts, or piped input), you'll hit this error:

Fatal error: Uncaught Symfony\Component\Console\Exception\MissingInputException: Aborted.
in vendor/symfony/console/Helper/QuestionHelper.php

The tool prompts for a directory list interactively. Fix it by piping an empty string to accept the default app directory:

echo "" | vendor/bin/filament-v4

You should see output like:

Start processing /app to fix code affected by breaking changes.
130/130 [============================] 100%
Finished processing /app.

What Rector Automatically Changes

In our project with 130 files (10 resources, 30 pages, 3 relation managers), Rector handled:

ChangeBefore (v3)After (v4)
Form method signatureForms\Form $formSchema $schema
Form return call$form->schema([...])$schema->components([...])
Table actions->actions([...])->recordActions([...])
Bulk actions->bulkActions([...])->toolbarActions([...])
Navigation icon type?stringstring | \BackedEnum | null
Navigation group type?stringstring | \UnitEnum | null
Import statementsNamespace aliases (Forms\Components\X)Explicit imports (use Filament\Forms\Components\X)
Page class referencesPages\ListEvents::route(...)ListEvents::route(...) with use import

Step 3: Update Composer Dependencies to Filament v4

After Rector finishes, it tells you to run two commands:

composer require filament/filament:"^4.0" -W --no-update
composer update

Fix: "Source directory has uncommitted changes" Error

During composer update, you may encounter:

Source directory vendor/nesbot/carbon has uncommitted changes.

This happens when a vendor package (like nesbot/carbon) has local modifications in its .git directory. Fix it by resetting the vendor package:

cd vendor/nesbot/carbon && git checkout .
cd /path/to/your/project
composer update

After a successful update, verify the installed version:

composer show filament/filament

Expected output:

name     : filament/filament
versions : * v4.7.0

New packages installed with Filament 4 include:

  • filament/schemas (the new Schema architecture)
  • filament/query-builder
  • chillerlan/php-qrcode
  • ueberdosis/tiptap-php
  • pragmarx/google2fa and pragmarx/google2fa-qrcode

Step 4: Fix Breaking Changes Rector Misses

This is the critical step most guides skip. Rector does not catch everything. In our upgrade, three breaking changes were missed across three resource files. You need to search for these patterns manually.

Find All Remaining Issues

Run this grep across your Filament directory:

grep -rn "callable \$get\|callable \$set\|MultiSelect\|->reactive()\|->json()" app/Filament/

If you see matches, fix them as shown below.

4a. Replace reactive() with live()

The ->reactive() method has been removed in Filament 4. Replace it with ->live().

Before (Filament 3):

Select::make('repeat_type')
    ->options([...])
    ->default('none')
    ->reactive(),

After (Filament 4):

Select::make('repeat_type')
    ->options([...])
    ->default('none')
    ->live(),

Verify with PHP:

php -r "echo method_exists('Filament\Forms\Components\Select', 'reactive') ? 'exists' : 'REMOVED';"
# Output: REMOVED

4b. Replace callable $get with Get $get

Filament 4 replaces the generic callable type hint with a dedicated Filament\Forms\Get class for form state access.

Before (Filament 3):

use Filament\Forms;

// In closures:
->visible(fn (callable $get) => $get('repeat_type') === 'custom')
->visible(fn (callable $get) => $get('repeat_type') !== 'none')

After (Filament 4):

use Filament\Forms\Get;

// In closures:
->visible(fn (Get $get) => $get('repeat_type') === 'custom')
->visible(fn (Get $get) => $get('repeat_type') !== 'none')

Don't forget to add the use Filament\Forms\Get; import at the top of your file. The same applies to Filament\Forms\Set if you use $set closures.

4c. Replace MultiSelect with Select->multiple()

The MultiSelect component has been completely removed in Filament 4. It's now a mode of the standard Select component.

Before (Filament 3):

use Filament\Forms\Components\MultiSelect;

MultiSelect::make('children')
    ->relationship('children', 'name')
    ->label('Children'),

After (Filament 4):

use Filament\Forms\Components\Select;

Select::make('children')
    ->multiple()
    ->relationship('children', 'name')
    ->label('Children'),

Verify the class is truly gone:

php -r "echo class_exists('Filament\Forms\Components\MultiSelect') ? 'exists' : 'REMOVED';"
# Output: REMOVED

4d. Replace ->json() on TextColumn

The ->json() method on TextColumn has been removed in Filament 4. Replace it with formatStateUsing().

Before (Filament 3):

Tables\Columns\TextColumn::make('data')
    ->label('Vitals Data')
    ->json()
    ->limit(50),

After (Filament 4):

Tables\Columns\TextColumn::make('data')
    ->label('Vitals Data')
    ->formatStateUsing(fn ($state) => is_array($state) ? json_encode($state) : $state)
    ->limit(50),

Verify:

php -r "echo method_exists('Filament\Tables\Columns\TextColumn', 'json') ? 'exists' : 'REMOVED';"
# Output: REMOVED

Step 5: Re-publish Filament Assets and Config

Filament 4 ships entirely new frontend assets (Tailwind CSS v4, new JS bundles, Inter font files). Delete the old ones and regenerate:

rm -rf public/css/filament public/js/filament
php artisan filament:assets

The new assets include a public/js/filament/schemas/ directory (for the new Schema architecture), updated component JS files, and Inter font woff2 files under public/fonts/filament/.

Re-publish the config file:

rm config/filament.php
php artisan vendor:publish --tag=filament-config

The new config/filament.php has significantly more options than v3's version. Notably, default_filesystem_disk now defaults to env('FILESYSTEM_DISK', 'local'). If your file uploads use ->disk('public') explicitly on each component, you're fine. Otherwise, check this setting.

Step 6: Clear All Caches

php artisan cache:clear
php artisan config:clear
php artisan view:clear
php artisan route:clear

Step 7: Remove the Upgrade Tool

The upgrade package and its dependencies (Rector, PHPStan) are no longer needed:

composer remove filament/upgrade --dev

This removes filament/upgrade, rector/rector, and phpstan/phpstan from your dev dependencies.

Complete Summary of Breaking Changes

Here's a reference table of every breaking change we encountered:

Breaking ChangeFilament 3Filament 4Rector Auto-Fix?
Form method signatureform(Forms\Form $form): Forms\Formform(Schema $schema): SchemaYes
Schema method$form->schema([...])$schema->components([...])Yes
Table row actions->actions([...])->recordActions([...])Yes
Bulk actions->bulkActions([...])->toolbarActions([...])Yes
Page class importsNamespace-relative Pages\ListXExplicit use importsYes
Navigation icon type hint?stringstring | \BackedEnum | nullYes
reactive()->reactive()->live()No
Closure type hintsfn (callable $get)fn (Get $get)No
MultiSelect componentMultiSelect::make()Select::make()->multiple()No
TextColumn json()->json()->formatStateUsing(fn ($state) => ...)No

Behavioral Changes (No Code Changes Needed)

These are new defaults in Filament 4 to be aware of:

  • Table filters are deferred by default — users must click "Apply" to trigger filters. If you have no filters defined, no impact.
  • Grid/Section components default to 1 column span — check your layouts if you use grid-based forms.
  • unique() validation ignores the current record by default — previously you had to add ->ignorable($record) manually.
  • File visibility defaults to private on non-local disks — if you use S3 or similar, you may need to set ->visibility('public') explicitly.

Verification

After the upgrade, verify everything works:

# Check routes register without errors
php artisan route:list --path=admin

# Syntax check key files
php -l app/Filament/Resources/EventResource.php
php -l app/Filament/Resources/ExpenseResource.php
php -l app/Filament/Resources/VitalResource.php

# Confirm no remaining deprecated APIs
grep -rn "callable \$get\|MultiSelect\|->reactive()\|->json()" app/Filament/

Then test in the browser at /admin:

  1. All resource list pages load without errors
  2. Create and edit forms render correctly
  3. Conditional fields (using ->live() + ->visible()) toggle properly
  4. Multi-select relationship fields work
  5. File uploads function on the correct disk
  6. Relation managers (like SplitsRelationManager) render in edit views
  7. Browser console shows no JavaScript errors

Conclusion

Upgrading from Filament 3 to Filament 4 is straightforward if you follow the right sequence: run the automated Rector tool first, then manually fix the four patterns it misses (reactive(), callable $get, MultiSelect, and json()). The whole process took us under 30 minutes for a project with 10 resources, 30 pages, and 3 relation managers.

The key takeaway: don't trust Rector blindly. Always grep your codebase for the patterns listed above after running the automated tool. The errors you'll get at runtime (Method reactive() not found, Class MultiSelect not found) are cryptic if you don't know what replaced them.


Need help upgrading your Laravel admin panel or migrating to Filament 4? Get in touch to discuss your project, or explore our web development services to see how we build high-quality Laravel applications.


Search Terms and Keywords Used

The following exact terms, commands, and technical phrases were used during this upgrade and are included for SEO indexing:

Commands executed:

  • composer require filament/upgrade:"^4.0" -W --dev
  • vendor/bin/filament-v4
  • echo "" | vendor/bin/filament-v4
  • composer require filament/filament:"^4.0" -W --no-update
  • composer update
  • composer show filament/filament
  • composer remove filament/upgrade --dev
  • php artisan filament:assets
  • php artisan vendor:publish --tag=filament-config
  • php artisan cache:clear
  • php artisan config:clear
  • php artisan view:clear
  • php artisan route:clear
  • php artisan route:list --path=admin

Error messages resolved:

  • Symfony\Component\Console\Exception\MissingInputException: Aborted
  • Source directory vendor/nesbot/carbon has uncommitted changes
  • Class Filament\Forms\Components\MultiSelect not found
  • Method reactive() does not exist
  • Method json() does not exist on Filament\Tables\Columns\TextColumn

Technical terms and search keywords:

  • upgrade filament 3 to filament 4
  • filament v4 migration guide
  • filament 4 breaking changes
  • filament php upgrade guide
  • filament 4 rector tool
  • filament reactive to live
  • filament MultiSelect removed
  • filament callable $get to Get $get
  • filament TextColumn json removed
  • filament Schema architecture v4
  • filament actions to recordActions
  • filament bulkActions to toolbarActions
  • filament Forms\Form to Filament\Schemas\Schema
  • laravel filament admin panel upgrade
  • filament 4 composer update
  • filament v3.3.45 to v4.7.0
  • filament 4 tailwind css v4
  • filament 4 new features
  • filament/schemas package
  • filament/query-builder package
  • filament default_filesystem_disk config
  • filament 4 table filters deferred
  • filament 4 unique validation ignores current record
Filament PHPLaravelPHPMigration Guide
Share this article:

Stay Updated

Get the latest insights delivered to your inbox.

No spam, unsubscribe anytime.

Need Help With Your Project?

Let's discuss how we can help bring your vision to life.

Get in Touch

Ready to Start Your Project?

Let's discuss how we can help transform your ideas into reality.