3/3/2025
Filament v4 — what changed and how to migrate from v3
TL;DR: Filament v4 changes signatures of key methods (form: Schema instead of Form, table Actions from a different namespace). Migration from v3: find+replace 5 patterns, takes an hour for a typical project.
Filament is one of those packages that changes how you build admin panels in Laravel. Version four is not an evolution — it’s a rethinking of the API informed by what was missing in v3. If you have a working project on v3, migration is inevitable — v3 won’t receive security fixes indefinitely.
Main API changes
The most important change concerns the signatures of form() and table() in resources. In v3:
public static function form(Form $form): Form
{
return $form->schema([...]);
}
In v4 Form is replaced by Schema:
use Filament\Schemas\Schema;
public static function form(Schema $schema): Schema
{
return $schema->components([...]);
}
The second key breaking change is the namespace for Actions in tables. In v3, Tables\Actions\EditAction and Filament\Actions\EditAction coexisted with some logic about when to use which. In v4 the namespace hierarchy is more clearly defined — all contextual table actions go through Filament\Tables\Actions, page header actions through Filament\Actions.
Third change: $navigationIcon must be declared as static:
// v3
protected ?string $navigationIcon = 'heroicon-o-users';
// v4
protected static ?string $navigationIcon = 'heroicon-o-users';
Fourth: the model type must be nullable:
// v3
protected static string $model = User::class;
// v4
protected static ?string $model = User::class;
Step-by-step migration
Start by updating composer:
composer update filament/filament
If there are conflicts — check the requirements of other packages. Many Filament v3 add-ons require separate updates to v4.
Then go through Filament’s CHANGELOG.md on GitHub — the list of breaking changes is comprehensive there. Key find+replace operations you can run automatically:
# Form -> Schema
find app/Filament -name "*.php" | xargs sed -i \
's/use Filament\\Forms\\Form;/use Filament\\Schemas\\Schema;/g'
find app/Filament -name "*.php" | xargs sed -i \
's/public static function form(Form \$form): Form/public static function form(Schema \$schema): Schema/g'
find app/Filament -name "*.php" | xargs sed -i \
's/return \$form->schema/return \$schema->components/g'
After the automated changes — manually review custom Pages. Pages inheriting from Filament\Pages\Page have changed $view signatures and other lifecycle methods. Review each one.
New features in v4
Filament v4 isn’t only breaking changes. New ColorPicker form component with support for HEX, RGB, HSL formats. TagsInput got a rewrite with better UX and autocomplete suggestions. Livewire wire:navigate is now more deeply integrated — navigation between resources without full page reload works smoothly out of the box.
StatsOverview widget changed its API to be more fluent:
// v4
protected function getStats(): array
{
return [
Stat::make('Users', User::count())
->description('Active this month')
->color('success')
->chart([7, 3, 4, 5, 6, 3, 5, 3]),
];
}
Migration pitfalls
The biggest pitfall is custom Pages — classes that extends Page or other Filament classes directly. Automatic find+replace won’t catch all contextual changes. Each such class requires manual review.
If you use Pest for testing the Filament panel, tests for custom Pages require rebuilding — the helpers have changed. livewire(EditUser::class) may require a different component setup.
Also check third-party packages (e.g. shield for roles, spatie/laravel-permission integrations) — they need to have compatible versions released for v4.
Summary
Filament v3 → v4 migration is mainly mechanical work: 5 find+replace patterns, manual review of custom Pages. For a standard CRUD project it takes 1–3 hours. The resulting API is cleaner and more consistent, and the new components plus Livewire performance improvements justify the effort.