Filament 5: What's New and How I Use It

Categories: Laravel
7 min read

My earlier post on Filament covered why it's my go-to Laravel admin panel for startups. This one goes further: what changed in v5, the patterns I keep coming back to across the Laravel projects I work on, which plugins earn their place, and what to watch out for.

What Changed in Filament 5

Filament 5 is a significant release. The jump from v3 to v5 touches almost every part of the framework, but the changes follow a clear direction: more composable, less magic, better tooling for complex apps.

Schemas: a unified component vocabulary

The biggest structural change is the introduction of schemas. In v3, forms and infolists had completely separate component vocabularies. In v5, both are built on a single schema system: form fields, infolist entries, and layout components can all live in the same schema. Forms and infolists are still distinct schemas in practice, but they're built from the same vocabulary, so the duplication that bothered me in v3 largely disappears.

The schema approach also makes it easier to share field definitions across resources. If several resources display the same address block or status badge, you can extract that schema fragment and reuse it cleanly.

Relation managers got smarter

Relation managers in v5 support more complex relationship types cleanly, including polymorphic relations that were awkward in v3. The attach/detach UX for many-to-many relations is improved, and pivot field handling is more explicit. For a multi-tenant app where tenants have relations to shared resources, this matters.

Plugin ecosystem maturing

The plugin API is steadier with each release, and the ecosystem is catching up. More and more often, when I need a piece of functionality, there's a plugin I'm actually happy to use rather than one I'd treat as a starting point to fork. Worth checking your plugin list carefully before upgrading - some have v5 branches, some have new package names - but the overall direction is good.

Patterns I Use in Production

I run Filament across several Laravel projects, including a multi-tenant SaaS where I'm freelance lead developer. Across those projects, a few patterns keep paying off.

Panel separation

Filament 5 lets you register multiple panels, and I lean on this whenever an app has more than one user type. On the multi-tenant SaaS, I run three panels: one for tenant-facing admin, one for super-admin operations, one for internal support tooling. Each has its own auth guard, middleware stack, and resource set. Cleaner than a single panel with role-based visibility logic: fewer conditional checks, less risk of leaking something across a boundary, simpler testing.

For multi-tenant apps, Filament's tenancy support scopes every Eloquent query to the authenticated tenant automatically. This isn't new in v5 (it worked the same way in v3) but it remains one of the features that makes Filament a strong fit for multi-tenant SaaS. The framework handles the scope; you handle the business logic.

Custom pages for non-resource workflows

Not everything fits a resource. Dashboards, reports, approval queues, bulk operations. Filament's custom page support is solid: you get a Livewire component with full access to Filament's layout, widgets, and action system. I use custom pages on most projects - onboarding wizards, settings screens, reporting views that pull from multiple models.

The pattern that works: keep custom pages thin. The page class handles layout and wires up Livewire properties; the heavy logic lives in action classes or service classes that you can test in isolation. Avoid putting database queries directly in page methods - they're hard to cache and hard to test.

Actions are where real work happens

Filament actions - table actions, page actions, bulk actions - are the best place to put admin operations that go beyond CRUD. Approve a subscription. Trigger a re-sync. Reset some piece of state. I use actions for these on every Filament project, each with a confirmation modal, success notification, and an audit log entry via Spatie Activitylog.

One thing that changed in v5: action modal forms use the schema API too. So I can build rich modal forms - conditional fields, dependent selects, validation - using the same API as resource forms. In v3 this was clunkier.

Plugin Choices: What I Use and Why

The Filament plugin ecosystem is large and uneven. Some plugins are production-ready; others are weekend projects. Here's what I actually use and why each earns its place.

Filament Shield

For permissions, I use Filament Shield (built on top of Spatie's permission package). It generates the permission set from your resources, pages, and widgets, and gives you a Filament UI for managing roles. On a project with several user types and a non-trivial permission matrix, this saves a lot of boilerplate. I treat it as the default starting point for any Filament project where authorisation is more than "admin sees everything".

Map picker

On apps that deal with physical locations, the map picker plugin gives me a Filament form field that renders an interactive map, lets the user pin a point, and writes lat/lng back to the form. The alternative was a custom Livewire component: similar effort, but I'd own the maintenance. For a field type that exists as a well-maintained plugin, that's not a good trade.

Media library (Spatie)

Spatie Media Library has first-party Filament support and I use it for image and document uploads across most projects. The integration is tight: the SpatieMediaLibraryFileUpload field handles the upload, conversion, and deletion within the Filament form without custom wiring. If you're already using Spatie Media Library, this is a straightforward addition.

Tags (Spatie)

Spatie Laravel Tags has a Filament field too. Lets users tag records from a pre-defined tag list with a single field declaration. No custom action needed.

When to build custom instead

I avoid plugins in two situations. First, when the plugin's abstraction doesn't match the data model and the workaround would be more code than writing the component from scratch. Second, when the plugin is poorly maintained - a repo with open bug reports and no recent activity is a liability. For anything that touches billing, permissions, or sensitive data, I lean towards owning the code.

Common Gotchas

Livewire component count

Every Filament resource page is a Livewire component. A panel with 20 resources and multiple pages per resource is a lot of Livewire components. PHP's autoloader handles this fine, but if you're not running php artisan filament:optimize (more on that below), cold requests will be noticeably slower as Filament discovers all your components at runtime.

N+1 in relation managers

Relation managers load related records, and it's easy to introduce N+1 queries without noticing. The symptom is a relation manager table that's slow to load and generates a flood of queries. Fix it with eager loading in the relation manager's getTableQuery() method, or by adding a global scope to the relationship. Laravel Debugbar or Telescope will show this quickly.

Omitting tenancy scope

On multi-tenant apps, the tenancy middleware that runs on page loads doesn't always cover async Livewire requests fired from inside Filament. Global search is one example. Searchable select dropdowns that query the database for options are another. Both can leak data across tenant boundaries if the underlying query isn't scoped. Worth verifying that tenant scope is active for those requests. A quick check with Telescope confirms it either way.

Policy coverage

Filament respects Laravel policies, but only if you wire them up. By default, in a panel without policies registered, all authenticated users can do everything. Filament Shield (above) handles a lot of this for you, but the principle stands: get the auth layer explicit early. Retrofitting is painful. This is one area where Laravel best practices for startups apply directly.

Performance: filament:optimize

Run php artisan filament:optimize as part of every production deploy. It caches Filament's component discovery and icon resolution, which have measurable overhead at runtime on larger panels. The difference on cold requests is significant once you've got a panel with 20+ resources. This is separate from php artisan optimize; both should run.

If you're on Laravel Cloud, add it to your build script alongside composer install and php artisan optimize. If you're on Forge, add it to your deploy script. It's one line and it pays for itself immediately.

Beyond that, standard Laravel performance advice applies: make sure your queue workers are running for any actions that trigger background work, cache config and routes, and use Horizon or Laravel Cloud's queue UI to keep an eye on throughput.

Upgrading from v3

The upgrade guide is thorough and the Filament team has kept a detailed changelog. In practice, the move to schemas is the largest migration task: form and infolist components have moved into a unified namespace, so you'll be touching most resource files. The relation manager improvements mostly just work, though complex pivot setups may need adjustment. Budget a day or two per panel for a real app - more if you have a lot of custom components or heavy plugin usage.

Is Filament 5 Worth It?

Yes. The schema unification alone removes a category of duplication that bothered me throughout v3 development. The action and modal improvements are real. The plugin ecosystem is more stable. If you're starting a new Laravel project with an admin panel requirement, there's no reason to reach for v3.

If you're on v3 in production and it's working, plan the upgrade but don't rush it. The new features are real, but so is the migration effort.

I'm a freelance Laravel developer based in Wiltshire, near Bath. If you're building or upgrading a Filament panel and want an experienced hand - whether that's the initial architecture, a v3 to v5 migration, or a production performance review - reach out.

Ben Lumley StackOverflow Github Linkedin

Related posts