liberusoftware/settings-filament
Filament integration for the Liberu settings package, giving Laravel apps an admin UI to view and manage application settings. Adds settings pages and forms to your Filament panel so configuration can be edited without touching code or config files.
This package is the admin UI layer only — a Filament page/plugin that renders whichever settings the companion liberusoftware/settings package exposes. Treat it as the presentation shell, not the source of truth. With 0 stars and 0 dependents there is no community documentation to lean on, so budget 20 minutes to read src/ before writing any code.
Minimal path:
composer require liberusoftware/settings liberusoftware/settings-filament
vendor/liberusoftware/settings-filament/composer.json and confirm the filament/filament requirement matches your panel's major version (v3 vs v4 differ substantially in page/plugin APIs). Mismatched majors are the single most likely reason this package "doesn't work."extra.laravel.providers in that composer.json. If the service provider isn't auto-registered, add it to bootstrap/providers.php (Laravel 11+) or config/app.php.src/ (typically SettingsFilamentPlugin or similar):public function panel(Panel $panel): Panel
{
return $panel
->plugin(\Liberusoftware\SettingsFilament\SettingsFilamentPlugin::make());
}
php artisan vendor:publish --provider="Liberusoftware\SettingsFilament\SettingsFilamentServiceProvider" — inspect the tag list with --list first rather than --all.php artisan route:list --path=settings. This tells you the slug, middleware, and whether the page landed where you expect.Where to look first, in this order: the plugin class → src/Pages/ or src/Resources/ (the actual Livewire form) → config/ (groups, field mapping, authorization) → the companion settings package's schema definition. Read the page's form() method; that schema is the contract between the two packages and tells you exactly what setting types are supported.
First use case: expose three or four scalar settings (site name, support email, maintenance toggle) in a "General" group, save them, and read them back via the core package's accessor in a Blade view. That end-to-end loop validates registration, schema mapping, persistence, and cache invalidation in one pass.
Keep schema definition in the core package, not the UI. The whole value of this split is that settings are readable from console commands, jobs, and queue workers without booting Filament. Define groups/fields in config or a service provider from liberusoftware/settings, and let this package render them. If you find yourself adding form fields only inside the Filament page, you've broken the model — the setting then has no non-UI definition.
Group → tab/section mapping. Most settings UIs of this shape map a group key to a Filament Tabs or Section. If the package doesn't do this automatically, wrap the generated schema in a Tabs component keyed on group name so a 40-setting admin page stays navigable. Verify whether ordering comes from config array order or an explicit sort key — don't assume.
Panel scoping. Register the plugin only on the admin panel, never a customer-facing one:
->plugin(SettingsFilamentPlugin::make())
->when(fn () => auth()->user()?->is_admin)
Better: put authorization behind a Gate (Gate::define('manage-settings', ...)) and reference it in config if the package supports a can_access / authorize callback. Check src/ for a canAccess() method on the page and override it via a subclass if the config hook is missing.
Cache invalidation is your responsibility until proven otherwise. Settings are almost always cached. After a save through the UI the package likely flushes; after a Settings::set() from a seeder, tinker, or migration it likely does not. Standardize on a single helper in your app that writes and flushes, and never call the raw setter directly from seeders.
Defaults and deployment. Ship defaults in config, not in a migration that inserts rows — otherwise fresh installs and upgrades diverge. Seed on AppServiceProvider::boot() only when the key is absent, or use php artisan settings:install if such a command exists.
Testing. Use Livewire component tests against the actual page class:
Livewire::test(SettingsPage::class)
->fillForm(['site_name' => 'Acme'])
->call('save')
->assertHasNoFormErrors();
$this->assertSame('Acme', Settings::get('site_name'));
That single test catches version drift, schema mismatches, and cache bugs — worth more than any amount of manual clicking.
Fork-readiness. At 0 stars with 0 dependents, assume you may need to patch. Keep your only integration points to (a) the plugin registration line and (b) a composer.json repositories VCS override or a thin subclass. Never edit vendor/.
The release metadata is suspect. A "last release" of 2026-10-27 is in the future relative to normal package timelines — a strong hint the versioning/tagging is auto-generated or the mirror is out of sync. Run composer show liberusoftware/settings-filament and check git tag on the repo before pinning. Pin to an explicit commit hash in composer.json for anything resembling production:
"liberusoftware/settings-filament": "dev-main#abc1234"
Filament v4 upgrade will break this. Filament removed/changed Form schema APIs, ->schema() vs ->form(), and page registration between v3 and v4. Since the package likely declares a wide constraint like ^3.0|^4.0, Composer will happily give you a combination that was never tested. Test the plugin page explicitly in your upgrade branch before touching other admin pages.
Double registration. If the package's service provider registers the plugin and you add ->plugin(...), you can get duplicate navigation items or a doubled form. If you see two "Settings" entries, remove your explicit registration first.
Stale reads after direct DB edits. Symptom: you change a value in TablePlus and the UI still shows the old one. Fix: find the cache key prefix in the core package's config and php artisan cache:forget it, or add a one-line artisan command wrapping the flush for your team.
File/image settings fail silently. Needs php artisan storage:link plus a disk that's actually configured. The field renders fine and the save looks successful while writing null. Always assert on the persisted value in tests, not just on assertHasNoFormErrors().
Secret settings get logged. Filament's password/revealable fields interact badly with request logging and Livewire payload dumps. If a setting is an API key, verify it's in $except for any logging middleware, and consider whether the value should round-trip to the browser at all — a "leave blank to keep current" pattern is safer than prefilling.
vendor:publish --force will eat your config edits. Publish once, then treat the published file as application code. Diff against the vendor copy on upgrade to catch new keys — missing config keys silently fall back to package defaults that may not match your intent.
Extension points to look for, in priority order: (1) a config-driven field-type map (custom setting type → Filament component class), (2) an overridable page class via Filament's page resolution or a ->view() call, (3) view files published to resources/views/vendor/. If none of the three exist, subclass the page and swap the schema in form() rather than forking.
Debugging tip: dump the resolved schema before touching the UI — ray($this->form->getFlatFields()) or dd() inside form(). Half the "field X doesn't appear" problems are a schema-group mismatch upstream, not a Filament rendering bug. Then check php artisan about to confirm the provider actually booted.
Don't let business logic leak into the page. Any validation, transformation, or side effect (e.g., "toggling maintenance mode dispatches an event") belongs in the core settings package or an observer, so it fires for CLI writes too. The Filament page should be a thin form over a service.
How can I help you explore Laravel packages today?