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. [  Filament v4: One Schema to Rule Them All ](#filament-v4-one-schema-to-rule-them-all)
2. [  What Changed at the API Level ](#what-changed-at-the-api-level)
3. [  Reusable Schema Objects ](#reusable-schema-objects)
4. [  Conditional Visibility Without Livewire Hacks ](#conditional-visibility-without-livewire-hacks)
5. [  Infolist Components in Read-Only Panels ](#infolist-components-in-read-only-panels)
6. [  Key Takeaways ](#key-takeaways)

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

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

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

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

       Table of contents

1. [  01   Filament v4: One Schema to Rule Them All  ](#filament-v4-one-schema-to-rule-them-all)
2. [  02   What Changed at the API Level  ](#what-changed-at-the-api-level)
3. [  03   Reusable Schema Objects  ](#reusable-schema-objects)
4. [  04   Conditional Visibility Without Livewire Hacks  ](#conditional-visibility-without-livewire-hacks)
5. [  05   Infolist Components in Read-Only Panels  ](#infolist-components-in-read-only-panels)
6. [  06   Key Takeaways  ](#key-takeaways)

 Filament v4: One Schema to Rule Them All
----------------------------------------

Filament v4 introduced a fundamental shift in how you define UI: forms and infolists no longer live in separate, parallel APIs with their own component namespaces. Instead, both are expressed through a **unified Schema API**. If you have built anything non-trivial in Filament v3, this is the change that will reshape your muscle memory the most.

This article focuses on the practical implications — what the unified schema looks like, how to share components between read and write contexts, and where the sharp edges are.

---

What Changed at the API Level
-----------------------------

In v3, a resource carried two distinct method signatures:

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

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

```

In v4, both methods accept a `Schema` object and draw from the same component pool:

```php
// Filament v4
use Filament\Schemas\Schema;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;

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

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

```

The `Schema` class is the common container. Components that are purely presentational (`TextEntry`, `ImageEntry`) remain in the `Infolists` namespace, while interactive components (`TextInput`, `Select`) stay in `Forms`. The container itself, however, is now shared.

---

Reusable Schema Objects
-----------------------

The real productivity gain is extracting shared schema fragments into plain PHP objects:

```php
namespace App\Filament\Schemas;

use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;

class AddressSchema
{
    public static function fields(): array
    {
        return [
            TextInput::make('street')->required(),
            TextInput::make('city')->required(),
            Select::make('country')
                ->options(Country::pluck('name', 'code'))
                ->searchable(),
        ];
    }
}

```

Then compose it anywhere:

```php
public static function form(Schema $schema): Schema
{
    return $schema->components([
        ...AddressSchema::fields(),
        TextInput::make('vat_number'),
    ]);
}

```

No traits, no abstract base resources — just arrays you spread. This is the pattern that scales.

---

Conditional Visibility Without Livewire Hacks
---------------------------------------------

Filament v4 tightens the `visible()` / `hidden()` API so conditions can reference sibling field state without wiring up custom Livewire properties:

```php
Select::make('billing_type')
    ->options([
        'individual' => 'Individual',
        'company'    => 'Company',
    ]),

TextInput::make('vat_number')
    ->visible(fn (Get $get): bool => $get('billing_type') === 'company')
    ->required(fn (Get $get): bool => $get('billing_type') === 'company'),

```

The `Get` callable is injected by the schema engine. No `$this->billingType` property needed on your Livewire component.

---

Infolist Components in Read-Only Panels
---------------------------------------

When you render a view page, Filament v4 passes the same `Schema` contract but the engine switches to read-only rendering automatically. You can still mix presentational and layout components:

```php
public static function infolist(Schema $schema): Schema
{
    return $schema->components([
        Section::make('Identity')->schema([
            TextEntry::make('name'),
            TextEntry::make('email'),
        ]),
        Section::make('Address')->schema(
            AddressSchema::entries() // read-only variant
        ),
    ]);
}

```

Keeping `::fields()` (interactive) and `::entries()` (read-only) as separate static methods on your schema class is the cleanest convention I have found.

---

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

- The `Schema` class is now the single container for both forms and infolists; stop importing two separate container types.
- Extract reusable schema fragments as plain PHP classes with static array-returning methods — spread them with `...`.
- `visible()` and `required()` closures receive a `Get` callable for reactive sibling access without extra Livewire state.
- Maintain separate `::fields()` and `::entries()` methods on shared schema objects to keep interactive and read-only components clearly separated.
- The component namespaces (`Forms\Components`, `Infolists\Components`) still exist; only the container is unified.

 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&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) 

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

  3 questions  

     Q01  Can I share a single schema definition for both the form and the infolist in Filament v4?        Not entirely — interactive components like TextInput cannot render in read-only infolist context. The practical pattern is a shared schema class with two static methods: one returning form fields and one returning infolist entries, keeping the layout logic DRY while using the correct component types for each context. 

      Q02  Does the unified Schema API break existing Filament v3 resources?        Yes. The method signatures change from `Form $form` and `Infolist $infolist` to `Schema $schema`, and the `-&gt;schema()` call becomes `-&gt;components()`. You will also need to update any imports that reference the old container classes. Running the Filament v4 upgrade command handles most of the mechanical renaming. 

      Q03  Is the Get callable in visible() closures reactive on every keystroke?        Yes. Filament wires the reactive dependency automatically when you use the Get callable inside visible(), hidden(), required(), or disabled(). The Livewire component re-evaluates those closures whenever the referenced field state changes, so there is no need to add extra reactive properties manually. 

  Continue reading

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

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

 [ ![PostgreSQL CTEs, Recursive Queries, and Lateral Joins in Laravel](https://cdn.msaied.com/241/32858f9c67eae0649999c32a6d31818f.png) laravel postgresql query-builder 

### PostgreSQL CTEs, Recursive Queries, and Lateral Joins in Laravel

Go beyond basic Eloquent with raw PostgreSQL power: composable CTEs, recursive tree traversal, and LATERAL joi...

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

 19 Jun 2026     3 min read  

  Read    

 ](https://msaied.com/articles/postgresql-ctes-recursive-queries-and-lateral-joins-in-laravel) [ ![PostgreSQL Window Functions in Laravel: Ranking, Running Totals, and Gap Detection](https://cdn.msaied.com/239/f588e7cbf8e6d3317a581ce0fa27140d.png) laravel postgresql eloquent 

### PostgreSQL Window Functions in Laravel: Ranking, Running Totals, and Gap Detection

Window functions let you compute rankings, running totals, and gaps directly in SQL without pulling rows into...

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

 19 Jun 2026     3 min read  

  Read    

 ](https://msaied.com/articles/postgresql-window-functions-in-laravel-ranking-running-totals-and-gap-detection) [ ![Custom Eloquent Casts: Encapsulating Domain Logic Inside Model Attributes](https://cdn.msaied.com/238/8e843e57a34f81f853eedefae629c09b.png) laravel eloquent domain-driven-design 

### Custom Eloquent Casts: Encapsulating Domain Logic Inside Model Attributes

Custom Eloquent casts let you push value-object logic directly into model attributes, keeping controllers and...

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

 19 Jun 2026     3 min read  

  Read    

 ](https://msaied.com/articles/custom-eloquent-casts-encapsulating-domain-logic-inside-model-attributes) 

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