Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Developer Experience Filament Laravel Package

liberusoftware/developer-experience-filament

A developer-experience toolkit for Filament and Laravel that bundles opinionated helpers, sensible defaults, and workflow conveniences to reduce boilerplate and speed up building, customizing, and maintaining admin panels. It aims to make everyday Filament development smoother and more predictable.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a presentation adapter: it ships Filament resources, pages, widgets and navigation for the liberusoftware/developer-experience domain module. It is not a standalone tool — the domain module (models, migrations, services, config) must already be installed, or the UI will render empty tables or throw class-not-found errors.

Minimum viable setup:

composer require liberusoftware/developer-experience-filament
php artisan vendor:publish --provider="Liberu\DeveloperExperience\Filament\DeveloperExperienceFilamentServiceProvider"
php artisan migrate   # only if the core domain module hasn't been migrated yet

Then register the plugin in the panel that should expose it — typically the internal/admin panel, not a customer-facing one:

// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        ->id('admin')
        ->path('admin')
        ->plugin(DeveloperExperienceFilamentPlugin::make());
}

Where to look first, in this order:

  1. vendor/liberusoftware/developer-experience-filament/src/Providers/ — the service provider tells you the truth: whether it registers a Filament plugin, publishes config/views/assets, or relies on resource discovery.
  2. src/Filament/Resources, src/Filament/Pages, src/Filament/Widgets — the actual surface area you'll be extending.
  3. config/developer-experience-filament.php — navigation group, sort order, feature toggles.
  4. composer.json — the filament/filament constraint. This is the single most important line in the package for you.

Verify registration worked before touching anything else:

php artisan route:list --path=admin | grep -i developer
php artisan about   # confirm the provider is booted

First use case: log into the panel, find the navigation group (likely "Developer Experience" / "System" / "Developer"), and exercise one listing resource end-to-end — open the list, create a record, edit it, delete it. That single loop validates the domain module wiring, policies, and form schema in one pass. If the group is missing, it's almost always a permissions problem rather than a registration problem.

Implementation Patterns

Keep the adapter dumb. Business logic belongs in the core module's services/actions. When you need behaviour the vendor resource doesn't have, inject the domain service into your subclass or into the resource's action closures rather than writing queries inside table():

->actions([
    Action::make('rotate')
        ->requiresConfirmation()
        ->action(fn ($record) => app(TokenRotator::class)->rotate($record)),
])

Extend, don't fork. Subclass the vendor resource and swap it in the panel. This survives composer update:

namespace App\Filament\Resources;

class ApiTokenResource extends \Liberu\DeveloperExperience\Filament\Resources\ApiTokenResource
{
    public static function getNavigationGroup(): ?string
    {
        return 'Access';
    }

    public static function getEloquentQuery(): Builder
    {
        return parent::getEloquentQuery()
            ->where('team_id', filament()->getTenant()?->id);
    }

    public static function getPages(): array
    {
        // keep parent pages, but point them at your resource
        return [
            'index'  => Pages\ListApiTokens::route('/'),
            'create' => Pages\CreateApiToken::route('/create'),
        ];
    }
}

If the plugin auto-discovers resources, you must exclude the vendor resource when registering your subclass (see Gotchas) or you'll get duplicate nav entries.

Custom pages and widgets. Prefer composing over overriding: add your own widgets to a vendor page by subclassing it and overriding getHeaderWidgets()/getFooterWidgets(). Only replace $view when you genuinely need different layout — copying the Blade file into resources/views/vendor/... is the lowest-friction override and upgrades predictably.

Multi-panel discipline. Register the plugin only where it belongs. Developer tooling in a customer panel is both a UX problem and a mild information-disclosure risk. If you need it in two panels, register it twice explicitly — do not register it in a shared base provider.

Authorization is your job. The adapter renders whatever the panel lets through. Pair every resource with a policy on the underlying model; use canViewAny(), shouldRegisterNavigation(), and gate checks on pages. If the core module ships permission names, seed them — otherwise non-super-admin users get silent 403s on pages that appear in the nav (Filament hides nav items inconsistently depending on version).

Testing pattern. Filament tests need the panel booted:

protected function setUp(): void
{
    parent::setUp();
    Filament::setCurrentPanel(Filament::getPanel('admin'));
}

it('lists tokens', function () {
    $this->actingAs(User::factory()->withPermission('view_api_tokens')->create());
    livewire(ListApiTokens::class)->assertCanSeeTableRecords(ApiToken::factory()->count(3)->create());
});

Use SQLite in-memory with the core module's migrations loaded. Clear component cache between test runs if you cache in CI: php artisan filament:clear-cached-components.

Local development against both packages. When you need to patch the adapter and the domain module together, use a path repository rather than editing vendor/:

"repositories": [{ "type": "path", "url": "../module-developer-experience-filament" }],
"require": { "liberusoftware/developer-experience-filament": "*" }

Theming. If you use a custom Filament theme, add the vendor view paths to your Tailwind content array — otherwise the adapter's classes get purged and it renders unstyled inside your theme but fine in the default one (a confusing failure mode).

Gotchas and Tips

Presentation-only means empty-is-not-broken. A blank table or "class not found" almost always means the core module is missing, its service provider isn't registered, or migrations haven't run. Check php artisan about and the provider list before you debug the adapter.

Treat this as first-party/internal code. Zero stars, zero dependents, NOASSERTION license, and a release date in the future. That combination means: read the source before relying on behaviour, pin an exact version ("1.2.3", not ^1.2), and don't assume semver. Budget for breaking changes on every bump. If you need to diverge significantly, vendor the resource into app/Filament and stop upgrading it.

Filament major-version skew is the #1 breaker. Filament v3 → v4 changed form/schema namespaces and resource APIs substantially. Before debugging your own code, run composer show filament/filament and compare against the adapter's constraint. A v3-only adapter in a v4 panel fails with confusing type errors at render time, not at install time.

Discovery duplicates. If the plugin auto-registers resources via discovery and you register a subclass, both appear. Fix by disabling the vendor resource's navigation (->registerNavigation(false) via configureUsing, or the package's own config toggle) or by excluding it in the plugin's resource list. Check the plugin class for a resources([...]) / discoverResources(false) style API.

Component caching in production. After any deploy that changes resources, pages or widgets, php artisan filament:cache-components must be re-run, and php artisan filament:clear-cached-components before it. Stale caches manifest as removed nav items still showing, or newly added pages 404ing.

Publish tags and asset quirks. vendor:publish --list (or reading publishes() in the provider) is faster than guessing tag names. Missing CSS/JS after publish usually means you ran vendor:publish without --force over an existing older copy.

Routing/403 debugging. These are Filament panel routes. php artisan route:list --path=admin tells you the real slugs. If you've changed the panel ->id() or ->path(), any hardcoded links in the adapter's views break — grep the views for route( and url(.

Render-hook collisions. Developer-experience packages commonly hook PanelsRenderHook::USER_MENU_* or the topbar. Two plugins doing the same produces doubled icons or broken Alpine state. Prefer navigation-group placement over render hooks when you're adding anything.

Unbounded queries in dev tooling. Health checks, log viewers and audit trails are the classic culprit for slow admin pages. Paginate, index the timestamp/tenant columns you filter on, and avoid ->poll() on widgets backed by large tables.

Extension preference order: config → subclass → view override → fork. Keep all custom code in app/Filament and register it from your own panel provider, so an upgrade is a one-line composer bump plus a re-run of filament:cache-components.

Support reality. With no dependents there are no public examples or Stack Overflow answers. Search the Liberu monorepo for real usage, and keep a short internal note of every override you make — future-you will be the only documentation this package has.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log