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: Unified Schema API in Practice        On this page       1. [  Filament v4 Schema-Based Forms: Unified Schema API in Practice ](#filament-v4-schema-based-forms-unified-schema-api-in-practice)
2. [  What Changed and Why It Matters ](#what-changed-and-why-it-matters)
3. [  Composing Reusable Schema Fragments ](#composing-reusable-schema-fragments)
4. [  Context-Specific Overrides ](#context-specific-overrides)
5. [  Custom Schema Components ](#custom-schema-components)
6. [  Performance Note ](#performance-note)
7. [  Key Takeaways ](#key-takeaways)

  ![Filament v4 Schema-Based Forms: Unified Schema API in Practice](https://cdn.msaied.com/173/6e0d9faa9137cb296e37831c3645e7ba.png)

  #filament   #laravel   #filament-v4   #schema-api  

 Filament v4 Schema-Based Forms: Unified Schema API in Practice 
================================================================

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

       Table of contents

1. [  01   Filament v4 Schema-Based Forms: Unified Schema API in Practice  ](#filament-v4-schema-based-forms-unified-schema-api-in-practice)
2. [  02   What Changed and Why It Matters  ](#what-changed-and-why-it-matters)
3. [  03   Composing Reusable Schema Fragments  ](#composing-reusable-schema-fragments)
4. [  04   Context-Specific Overrides  ](#context-specific-overrides)
5. [  05   Custom Schema Components  ](#custom-schema-components)
6. [  06   Performance Note  ](#performance-note)
7. [  07   Key Takeaways  ](#key-takeaways)

 Filament v4 Schema-Based Forms: Unified Schema API in Practice
--------------------------------------------------------------

Filament v4 introduced one of its most architecturally significant changes: a **unified Schema API** that replaces the previously separate `form()` and `infolist()` definition styles with a single, composable `schema()` surface. If you have a non-trivial Filament v3 codebase, understanding this shift before you migrate will save you hours of confusion.

### What Changed and Why It Matters

In Filament v3, forms and infolists lived in parallel universes. You defined `form(Form $form)` with `Components\TextInput`, and separately `infolist(Infolist $infolist)` with `Entries\TextEntry`. The duplication was real — the same field often had a twin entry just to display it read-only.

Filament v4 collapses this into a single `schema(Schema $schema)` method. Components are now context-aware: a `TextInput` can render as an editable field inside a form context and as a read-only entry inside an infolist context, driven by the same definition.

```php
use Filament\Schema\Schema;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;

public function schema(Schema $schema): Schema
{
    return $schema->components([
        TextInput::make('name')
            ->required()
            ->maxLength(255),

        Select::make('status')
            ->options(Status::class)
            ->native(false),
    ]);
}

```

The same array powers both the create/edit form and the view infolist. No more maintaining two lists.

### Composing Reusable Schema Fragments

The real power emerges when you extract domain-specific schema fragments into dedicated classes. Think of these as DTOs for your UI structure.

```php
namespace App\Filament\Schemas;

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\DatePicker;

final class AddressSchema
{
    public static function make(string $prefix = ''): array
    {
        $field = fn(string $name) => $prefix ? "{$prefix}.{$name}" : $name;

        return [
            Fieldset::make('Address')
                ->schema([
                    TextInput::make($field('line1'))->required(),
                    TextInput::make($field('city'))->required(),
                    TextInput::make($field('postcode'))->required(),
                ]),
        ];
    }
}

```

Now any resource that needs an address block calls `AddressSchema::make('billing')` — one definition, zero drift between form and infolist.

### Context-Specific Overrides

Sometimes a field genuinely needs different behaviour in edit vs. view mode. The Schema API provides `->hiddenOn()` and `->visibleOn()` helpers, plus the `->formatStateUsing()` callback that only fires during infolist rendering.

```php
TextInput::make('api_key')
    ->password()
    ->revealable()
    ->hiddenOn('view'), // hide raw key in infolist

TextEntry::make('api_key')
    ->formatStateUsing(fn($state) => '••••' . substr($state, -4))
    ->visibleOn('view'),

```

This pattern keeps sensitive fields safe without splitting your schema definition.

### Custom Schema Components

Building a custom component is now a single class that extends `Component` and declares both its form and infolist views.

```php
namespace App\Filament\Components;

use Filament\Forms\Components\Component;

class MoneyInput extends Component
{
    protected string $view = 'filament.components.money-input';

    public static function make(string $name): static
    {
        return app(static::class, ['name' => $name]);
    }
}

```

The Blade view receives `$getState()`, `$isDisabled()`, and the full component API — no separate `Entry` class required.

### Performance Note

Because the Schema API resolves components lazily and shares the same component tree for both read and write contexts, Filament v4 avoids instantiating duplicate component graphs per page load. On resource pages with 30+ fields this is a measurable reduction in object allocations, though the gains are most visible under Octane where those allocations compound across requests.

### Key Takeaways

- **One `schema()` method** replaces both `form()` and `infolist()` in Filament v4.
- Extract reusable field groups into **static schema fragment classes** to eliminate duplication.
- Use `->visibleOn()` / `->hiddenOn()` for context-specific rendering without splitting definitions.
- Custom components now require **one class and one view**, not a form component plus an infolist entry.
- The unified tree means fewer object allocations, which matters under long-running runtimes like Octane.

 Found this useful?

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

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

  3 questions  

     Q01  Can I still use the old form() and infolist() methods in Filament v4?        Filament v4 deprecates the separate form() and infolist() methods in favour of the unified schema() API. The old methods may still work during a transition period, but new resources should use schema() to avoid future breaking changes. 

      Q02  How do I handle fields that should only appear in edit mode, not view mode?        Use -&gt;hiddenOn('view') on the component, or -&gt;visibleOn('create', 'edit'). For display-only variants, define a companion TextEntry with -&gt;visibleOn('view') in the same schema array. 

      Q03  Do third-party Filament v3 plugins work with the v4 Schema API?        Plugins that extend Form components or Infolist entries need to be updated by their maintainers to implement the unified Component contract. Check the plugin's changelog for v4 compatibility before upgrading. 

  Continue reading

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

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

 [ ![Eloquent Custom Casts: Encapsulating Value Objects Without the Bloat](https://cdn.msaied.com/174/2c75896ee4182bb2f66e2c93bed18796.png) laravel eloquent ddd 

### Eloquent Custom Casts: Encapsulating Value Objects Without the Bloat

Custom Eloquent casts let you bind rich value objects directly to model attributes. This article shows how to...

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

 14 Jun 2026     1 min read  

  Read    

 ](https://msaied.com/articles/eloquent-custom-casts-encapsulating-value-objects-without-the-bloat) [ ![The Pipeline Pattern in Laravel: Building Custom Pipelines Beyond Middleware](https://cdn.msaied.com/172/a5dea5e84a6eab22d5d7a76869aaecb4.png) laravel design-patterns pipeline 

### The Pipeline Pattern in Laravel: Building Custom Pipelines Beyond Middleware

Laravel's Pipeline class is far more than the engine behind HTTP middleware. Learn how to compose reusable, te...

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

 14 Jun 2026     3 min read  

  Read    

 ](https://msaied.com/articles/the-pipeline-pattern-in-laravel-building-custom-pipelines-beyond-middleware) [ ![Read/Write Splitting, Connection Pooling, and Sticky Reads in Laravel](https://cdn.msaied.com/171/92ea6daa5c8b599f43ef1c69a7c1eaa6.png) laravel database performance 

### Read/Write Splitting, Connection Pooling, and Sticky Reads in Laravel

Learn how Laravel's database layer handles read/write splitting, when sticky reads save you from replication l...

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

 14 Jun 2026     4 min read  

  Read    

 ](https://msaied.com/articles/readwrite-splitting-connection-pooling-and-sticky-reads-in-laravel) 

   [  ![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)
