Filament v4 Unified Schema API: Forms &amp; Infolists | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API        On this page       1. [  Why Filament v4 Rewrote the Component Model ](#why-filament-v4-rewrote-the-component-model)
2. [  The Schema Component Tree ](#the-schema-component-tree)
3. [  Extracting a Shared Schema Method ](#extracting-a-shared-schema-method)
4. [  Schema Components in Custom Pages and Widgets ](#schema-components-in-custom-pages-and-widgets)
5. [  What Actually Breaks When Upgrading ](#what-actually-breaks-when-upgrading)
6. [  Namespace changes ](#namespace-changes)
7. [  -&gt;columns() on Section ](#code-gtcolumnscode-on-codesectioncode)
8. [  Custom field getChildComponents() ](#custom-field-codegetchildcomponentscode)
9. [  Takeaways ](#takeaways)

  ![Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API](https://cdn.msaied.com/360/11c59afcba98933101f65c6357f5cd1c.png)

  #filament   #laravel   #filament-v4   #admin-panel  

 Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API 
=======================================================================

     4 Jul 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

  9 sections  

1. [  01   Why Filament v4 Rewrote the Component Model  ](#why-filament-v4-rewrote-the-component-model)
2. [  02   The Schema Component Tree  ](#the-schema-component-tree)
3. [  03   Extracting a Shared Schema Method  ](#extracting-a-shared-schema-method)
4. [  04   Schema Components in Custom Pages and Widgets  ](#schema-components-in-custom-pages-and-widgets)
5. [  05   What Actually Breaks When Upgrading  ](#what-actually-breaks-when-upgrading)
6. [  06   Namespace changes  ](#namespace-changes)
7. [  07   -&gt;columns() on Section  ](#code-gtcolumnscode-on-codesectioncode)
8. [  08   Custom field getChildComponents()  ](#custom-field-codegetchildcomponentscode)
9. [  09   Takeaways  ](#takeaways)

       Why Filament v4 Rewrote the Component Model
-------------------------------------------

In Filament v3 you maintained two parallel trees: `form(Form $form)` returned `$form->schema([...])` and `infolist(Infolist $infolist)` returned `$infolist->schema([...])`. The components were different classes even when they displayed the same data — a `TextInput` for editing, a `TextEntry` for viewing. Filament v4 collapses this into a **unified Schema API** where a single component tree can render in both contexts, and dedicated entry components are first-class citizens alongside field components.

---

The Schema Component Tree
-------------------------

Every layout wrapper — `Section`, `Grid`, `Tabs`, `Fieldset` — now lives under `Filament\Schemas\Components\` and is shared between forms and infolists. You import them once and use them everywhere.

```php
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Grid;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;

public static function form(Form $form): Form
{
    return $form->schema([
        Section::make('Identity')
            ->schema([
                Grid::make(2)->schema([
                    TextInput::make('name')->required(),
                    TextInput::make('email')->email()->required(),
                ]),
            ]),
    ]);
}

public static function infolist(Infolist $infolist): Infolist
{
    return $infolist->schema([
        Section::make('Identity')
            ->schema([
                Grid::make(2)->schema([
                    TextEntry::make('name'),
                    TextEntry::make('email'),
                ]),
            ]),
    ]);
}

```

The `Section` and `Grid` imports are identical. Only the leaf components differ.

---

Extracting a Shared Schema Method
---------------------------------

Because layout wrappers are now the same class, you can extract the skeleton into a static helper and swap only the leaves.

```php
private static function identitySchema(array $fields): array
{
    return [
        Section::make('Identity')
            ->schema([
                Grid::make(2)->schema($fields),
            ]),
    ];
}

public static function form(Form $form): Form
{
    return $form->schema(self::identitySchema([
        TextInput::make('name')->required(),
        TextInput::make('email')->email()->required(),
    ]));
}

public static function infolist(Infolist $infolist): Infolist
{
    return $infolist->schema(self::identitySchema([
        TextEntry::make('name'),
        TextEntry::make('email'),
    ]));
}

```

This pattern eliminates the structural duplication that plagued v3 resources with large schemas.

---

Schema Components in Custom Pages and Widgets
---------------------------------------------

Custom pages that previously called `$this->form->fill()` now use `HasForms` or `HasInfolists` traits alongside the schema builder. The `$this->form(...)` and `$this->infolist(...)` calls accept the same unified component classes.

```php
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Schemas\Components\Section;

class EditProfilePage extends Page
{
    use InteractsWithForms;

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Section::make()->schema([
                    TextInput::make('bio')->columnSpanFull(),
                ]),
            ])
            ->statePath('data');
    }
}

```

---

What Actually Breaks When Upgrading
-----------------------------------

### Namespace changes

Any import of `Filament\Forms\Components\Section` or `Filament\Forms\Components\Grid` must move to `Filament\Schemas\Components\`. A project-wide find-and-replace handles most of it.

### `->columns()` on `Section`

In v3 you called `->columns(2)` on `Section` directly. In v4 you wrap children in `Grid::make(2)` instead. The old shorthand still works as a compatibility shim in early v4 releases, but the canonical approach is explicit `Grid`.

### Custom field `getChildComponents()`

If you built custom layout components by extending `Filament\Forms\Components\Component`, the base class has moved. Extend `Filament\Schemas\Components\Component` instead and implement `getChildComponents()` as before.

---

Takeaways
---------

- Layout components (`Section`, `Grid`, `Tabs`) are now shared across forms and infolists under `Filament\Schemas\Components\`.
- Leaf components (`TextInput`, `TextEntry`) remain context-specific but sit inside the same tree.
- Extracting a shared schema skeleton method removes structural duplication across `form()` and `infolist()`.
- The main upgrade cost is namespace replacement and swapping `->columns()` shortcuts for explicit `Grid` wrappers.
- Custom layout components must extend the new base class in `Filament\Schemas\Components\`.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffilament-v4-schema-based-forms-infolists-and-the-unified-schema-api-2&text=Filament+v4+Schema-Based+Forms%2C+Infolists%2C+and+the+Unified+Schema+API) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffilament-v4-schema-based-forms-infolists-and-the-unified-schema-api-2) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Can I use a single component for both editing and viewing in Filament v4?        Not for leaf components — TextInput is still edit-only and TextEntry is view-only. The unification applies to layout wrappers like Section and Grid, which are now the same class in both contexts. 

      Q02  Do I need to update every resource immediately after upgrading to Filament v4?        Filament v4 ships compatibility shims for the most common v3 form namespace imports, so many resources continue to work. However, the shims are not guaranteed across minor releases, so migrating namespaces early is strongly recommended. 

      Q03  Where should custom layout components extend from in Filament v4?        Extend Filament\Schemas\Components\Component instead of the old Filament\Forms\Components\Component. The API for getChildComponents() and childComponents() remains the same. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Object Storage Migrations with Laravel's Read-Through Filesystem](https://cdn.msaied.com/565/f830d15d4a1287d381fa05e631ea2aba.png) Laravel 13 Object Storage S3 

### Object Storage Migrations with Laravel's Read-Through Filesystem

Laravel 13 introduces a read-through filesystem driver that lets you migrate from S3 to R2 without downtime. N...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 18 Aug 2026     4 min read  

  Read    

 ](https://msaied.com/articles/object-storage-migrations-with-laravels-read-through-filesystem) [ ![Livewire v4.4.1 Released: Bug Fixes, Alpine 3.16.2, and Laravel 13 Compatibility](https://cdn.msaied.com/564/c64b65959ad8ade491c78f3482f22996.png) Livewire Laravel Alpine.js 

### Livewire v4.4.1 Released: Bug Fixes, Alpine 3.16.2, and Laravel 13 Compatibility

Livewire v4.4.1 ships 16 fixes and improvements including Alpine.js bumped to 3.16.2, cached computed property...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 18 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/livewire-v441-released-bug-fixes-alpine-3162-and-laravel-13-compatibility) [ ![MySQL EXPLAIN and Query Profiling in Laravel: Finding Slow Queries Before They Hit Production](https://cdn.msaied.com/563/f2d4a7fb0ab45706cf9330746f7b2588.png) laravel mysql performance 

### MySQL EXPLAIN and Query Profiling in Laravel: Finding Slow Queries Before They Hit Production

Learn how to read MySQL EXPLAIN output, use query profiling tools, and integrate them into a Laravel workflow...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 18 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/mysql-explain-and-query-profiling-in-laravel-finding-slow-queries-before-they-hit-production) 

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

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
