Filament v3 vs v4 vs v5: What Changed and Why It Matters

 











If you've been building Laravel admin panels with Filament, you've probably noticed the project has evolved rapidly. Three major versions in a relatively short window — v3, v4, and now v5 — each with its own philosophy and set of trade-offs. This post breaks down what actually changed, version by version.

Requirements at a Glance

Requirement

v3

v4

v5

PHP

8.1+

8.2+

8.2+

Laravel

10+

11 or 12

11 or 12

Livewire

3.x

3.x

4.x

Tailwindcss

3.x

4.x

4.x

The Schema Unification (v3 → v4)

This is the most significant architectural change in the v3-to-v4 migration, and it touches almost every resource file in your project.

In v3, form components, infolist components, and layout components all lived in separate namespaces:

// v3 — separate namespaces for each context
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\Section; // conflict!
use Filament\Infolists\Components\TextEntry;

In v4/v5, these are unified under Filament\Schemas:

// v4/v5 — unified schema namespace
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;

Actions Get Simpler (v3 → v4)

// v3 — different Action class depending on where you use it
use Filament\Tables\Actions\Action;
use Filament\Forms\Components\Actions\Action;
use Filament\Infolists\Components\Actions\Action;

In v4/v5, all actions collapse to a single namespace:

// v4/v5 — one Action class, works everywhere
use Filament\Actions\Action;

Resource Organisation and Code Structure (v3 → v4)

In v3, resources tended to get monolithic quickly. The form() and table() methods could easily grow to hundreds of lines inside a single resource class.

v4 introduces a proper separation of concerns: resource classes are now generated within dedicated namespaces, and the recommendation is to extract large form and table definitions into their own schema/table class files. For example:

app/
  Filament/
    Resources/
      EnquiryResource.php
      EnquiryResource/
        Pages/
          ListEnquiries.php
          CreateEnquiry.php
          EditEnquiry.php
        Schemas/
          EnquiryForm.php      ← form definition in its own class
        Tables/
          EnquiryTable.php     ← table definition in its own class

This isn't mandatory, but it's the idiomatic v4/v5 approach — and it makes large resources significantly easier to navigate and test.

Layout Defaults Changed (v3 → v4)

One subtle but impactful change: Grid, Section, and Fieldset components changed their default column span behaviour.

In v3, these components consumed the full width of their parent grid by default. In v4/v5, they consume one column by default — consistent with every other component. If you want the old behaviour, you now need to be explicit:

// v4/v5 — restore full-width behaviour
Section::make('Details')
    ->columnSpanFull()
    ->schema([...])

This will silently break the visual layout of existing forms after migration if you don't check for it. The upgrade script doesn't handle this one — you need to audit your layouts manually.

Tenancy Scoping (v3 → v4)

If you're using multi-tenancy, v4 made a meaningful improvement here.

In v3, Filament only automatically scoped queries to the current tenant in three specific places: rendering the resource table, resolving URL parameters, and fetching global search results. Everything else — relation managers, custom pages, actions — required manual scoping.

In v4/v5, the panel automatically scopes all queries to the current tenant, and new records are automatically associated with the current tenant via model events. This eliminates a whole class of security footguns that v3 developers had to consciously guard against.

The Rich Editor Swap (v3 → v4)

V3 Rich-editor

V5 Rich-editor

FeatureFilament v3 RichEditorFilament v5 RichEditor
Editor engineTrixTiptap
Filament versionv3v5
Content storage (default)HTMLHTML
JSON storage supportNoYes (->json())
Toolbar customizationLimitedMore flexible
Custom blocksNoYes
Merge tags ({{ name }})NoYes
Extension ecosystemSmallLarge (Tiptap ecosystem)
Structured content supportLimitedStrong
Drag-and-drop content blocksNoYes
Existing HTML compatibilityN/AExisting Trix HTML usually works
Migration effortUsually low, but testing recommended
Rendering outside FilamentStandard HTMLHTML or JSON depending on configuration
v3v5
php<br>RichEditor::make('content')<br> ->toolbarButtons([<br> 'bold',<br> 'italic',<br> ]);<br>php<br>RichEditor::make('content')<br> ->toolbarButtons([<br> 'bold',<br> 'italic',<br> ])<br> ->json();<br>

Livewire Shift (v3 vs. v4)

FeatureLivewire 3Livewire 4
Component structurePHP class + Blade viewClass/View or Single-File Components
Alpine integrationBuilt-inBuilt-in
wire:model defaultDeferredDeferred
wire:navigateImproved
SPA-like navigationImproved
Volt supportOptionalFirst-class experience
Single-File ComponentsVia VoltNative SFC support
wire:showBasicImproved
wire:text
$js actionsLimitedExpanded
Partial renderingComponent-levelIsland architecture
Independent updatesLimitedIslands
Client-side interactivityModerateGreater
PerformanceGoodImproved hydration and rendering

Comments