Filament v3 to v4 Migration: Breaking Changes | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. Filament v4 Migrating from v3: Breaking Changes and Refactor Patterns

 Filament v4 Migrating from v3: Breaking Changes and Refactor Patterns
======================================================================

 A practical, opinionated guide to the most impactful Filament v3→v4 breaking changes: schema-based forms, the unified component API, removed helpers, and the refactor patterns that keep your panels clean.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 26 Jul 2026 · Updated 26 Jul 2026 · 4 min read

ShareCopy linkCopied

 ![Filament v4 Migrating from v3: Breaking Changes and Refactor Patterns](https://cdn.msaied.com/472/bb7fbf8441c775fcfadd23850e1756e8.png) 

  On this page +1. [Why v3→v4 Is a Real Migration, Not a Bump](#why-v3v4-is-a-real-migration-not-a-bump)
2. [1. The Schema API Replaces Separate form() and infolist() Builders](#1-the-schema-api-replaces-separate-codeformcode-and-codeinfolistcode-builders)
3. [2. -&gt;schema() → -&gt;components() on Layouts](#2-code-gtschemacode-code-gtcomponentscode-on-layouts)
4. [3. Removed Static Helpers on Action](#3-removed-static-helpers-on-codeactioncode)
5. [4. Table Column -&gt;getStateUsing() Signature Change](#4-table-column-code-gtgetstateusingcode-signature-change)
6. [5. Refactor Pattern: Extract a SchemaBuilder Class](#5-refactor-pattern-extract-a-codeschemabuildercode-class)
7. [Key Takeaways](#key-takeaways)

 Why v3→v4 Is a Real Migration, Not a Bump
-----------------------------------------

Filament v4 is not a cosmetic release. The team unified forms, infolists, and table columns under a single **Schema API**, removed a handful of convenience statics, and changed how component state flows through resources. If you have a mid-size panel with 20+ resources, expect a focused but non-trivial refactor.

This article walks through the highest-impact changes with concrete before/after examples.

---

1. The Schema API Replaces Separate `form()` and `infolist()` Builders
----------------------------------------------------------------------

In v3, `form()` returned a `Form` and `infolist()` returned an `Infolist`. In v4 both accept a `Schema` and share the same component tree.

**v3**

```php
public static function form(Form $form): Form
{
    return $form->schema([
        Forms\Components\TextInput::make('name')->required(),
    ]);
}

public static function infolist(Infolist $infolist): Infolist
{
    return $infolist->schema([
        Infolists\Components\TextEntry::make('name'),
    ]);
}

```

**v4**

```php
use Filament\Schemas\Schema;

public static function form(Schema $schema): Schema
{
    return $schema->components([
        Forms\Components\TextInput::make('name')->required(),
    ]);
}

public static function infolist(Schema $schema): Schema
{
    return $schema->components([
        Infolists\Components\TextEntry::make('name'),
    ]);
}

```

The method signature change is the first thing your IDE will flag. Run a project-wide search for `Form $form` and `Infolist $infolist` in resource files.

---

2. `->schema()` → `->components()` on Layouts
---------------------------------------------

Every layout component (`Grid`, `Section`, `Fieldset`, `Tabs\Tab`, etc.) that previously accepted `->schema([...])` now uses `->components([...])`.

```php
// v3
Forms\Components\Section::make('Details')
    ->schema([
        Forms\Components\TextInput::make('email'),
    ]);

// v4
Forms\Components\Section::make('Details')
    ->components([
        Forms\Components\TextInput::make('email'),
    ]);

```

This is the most widespread mechanical change. A simple regex replacement handles 90% of it:

```bash
# dry-run first
grep -rn '->schema(\[' app/Filament

# replace (macOS sed)
find app/Filament -name '*.php' \
  -exec sed -i '' 's/->schema(\[/->components([/g' {} +

```

Verify manually — `->schema()` still exists on the root `Schema` object itself, so a blanket replace will over-correct.

---

3. Removed Static Helpers on `Action`
-------------------------------------

Several static convenience methods on `Action` were removed in favour of explicit closures.

```php
// v3 — no longer exists
Action::make('approve')
    ->requiresConfirmation()
    ->successNotificationTitle('Approved');

// v4 — use notification() explicitly
Action::make('approve')
    ->requiresConfirmation()
    ->successNotification(
        Notification::make()->title('Approved')->success()
    );

```

Check the changelog for the full list; `->failureNotificationTitle()` and `->successNotificationTitle()` are both gone.

---

4. Table Column `->getStateUsing()` Signature Change
----------------------------------------------------

Custom columns that used `->getStateUsing(fn ($record) => ...)` now receive a typed `$state` parameter when chained after `->state()`.

```php
// v4 — explicit state pipeline
TextColumn::make('status_label')
    ->state(fn (Order $record): string => $record->status->value)
    ->formatStateUsing(fn (string $state): string => Str::title($state));

```

Separating state resolution from formatting is cleaner and easier to test in isolation.

---

5. Refactor Pattern: Extract a `SchemaBuilder` Class
----------------------------------------------------

For large resources, avoid bloating `form()` and `infolist()` with inline logic. Extract a dedicated class:

```php
final class OrderSchemaBuilder
{
    public static function form(): array
    {
        return [
            TextInput::make('reference')->required(),
            Select::make('status')->options(OrderStatus::class),
        ];
    }

    public static function infolist(): array
    {
        return [
            TextEntry::make('reference'),
            TextEntry::make('status')->badge(),
        ];
    }
}

// In OrderResource
public static function form(Schema $schema): Schema
{
    return $schema->components(OrderSchemaBuilder::form());
}

```

This pattern survives future API shifts because the resource itself becomes a thin adapter.

---

Key Takeaways
-------------

- `Form $form` / `Infolist $infolist` signatures become `Schema $schema` — update every resource.
- `->schema([])` on layout components becomes `->components([])` — automate with a careful find-replace.
- `->successNotificationTitle()` and `->failureNotificationTitle()` are removed; use `->successNotification()` with a `Notification` object.
- Separate state resolution (`->state()`) from formatting (`->formatStateUsing()`) in table columns.
- Extract `SchemaBuilder` classes for large resources to isolate your domain logic from Filament's API surface.

- [filament](https://www.msaied.com/public/articles?search=filament)
- [laravel](https://www.msaied.com/public/articles?search=laravel)
- [migration](https://www.msaied.com/public/articles?search=migration)
- [filament-v4](https://www.msaied.com/public/articles?search=filament-v4)

 Frequently asked questions 
---------------------------

  Can I migrate resources one at a time, or does v4 require all-at-once?Filament v4 is a hard dependency upgrade, so all resources must be compatible before you can run the application. However, you can batch the mechanical changes (schema/components rename) with a script and then address the action/notification API changes resource by resource.

   Does the `-&gt;schema()` method still exist anywhere in v4?Yes — the root `Schema` object passed into `form()` and `infolist()` still exposes `-&gt;components()` as the primary method. The `-&gt;schema()` alias was removed from layout components like Section and Grid, which is where the confusion arises.

   Are custom Filament v3 field plugins compatible with v4 out of the box?Usually not without changes. Plugins that extend `Field` or `Column` and call `-&gt;schema()` internally need updating. Check the plugin's GitHub issues or changelog before upgrading, and pin the plugin version until the maintainer ships a v4-compatible release.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleConcurrency in Laravel: Process Pools, Fibers, and the Concurrency Facade](https://www.msaied.com/public/articles/concurrency-in-laravel-process-pools-fibers-and-the-concurrency-facade) [Next articleProfiling Laravel with Blackfire and Xdebug: Finding Real Bottlenecks](https://www.msaied.com/public/articles/profiling-laravel-with-blackfire-and-xdebug-finding-real-bottlenecks-1)  

   On this page
-------------

1. [Why v3→v4 Is a Real Migration, Not a Bump](#why-v3v4-is-a-real-migration-not-a-bump)
2. [1. The Schema API Replaces Separate form() and infolist() Builders](#1-the-schema-api-replaces-separate-codeformcode-and-codeinfolistcode-builders)
3. [2. -&gt;schema() → -&gt;components() on Layouts](#2-code-gtschemacode-code-gtcomponentscode-on-layouts)
4. [3. Removed Static Helpers on Action](#3-removed-static-helpers-on-codeactioncode)
5. [4. Table Column -&gt;getStateUsing() Signature Change](#4-table-column-code-gtgetstateusingcode-signature-change)
6. [5. Refactor Pattern: Extract a SchemaBuilder Class](#5-refactor-pattern-extract-a-codeschemabuildercode-class)
7. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
