saivra/meui-theme
MEUI Theme is a Laravel package that adds a ready-to-use MEUI admin interface theme to PHP applications. It provides Blade views, assets, and configurable layout components to quickly style dashboards and back-office panels.
MeUI is a Filament 5 panel theme for Laravel 12/13. Start theme-only, then opt into personal customization once the baseline look is accepted.
composer require saivra/meui-theme
php artisan filament:assets
Register the plugin in each panel provider you want themed:
use Saivra\MeUiTheme\MeUiPlugin; // confirm the vendor namespace from the installed package
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugin(MeUiPlugin::make());
}
First use case: apply the theme to an existing admin panel, check the dashboard, tables, forms, and split auth screens in both light and dark mode. Then enable the customizer for a small pilot group (e.g. admins) before exposing it to every signed-in user.
To enable the included database-backed customizer:
php artisan vendor:publish --tag=meui-migrations
php artisan migrate
->plugin(MeUiPlugin::make()->customizer())
This adds a Customize theme profile action for signed-in panel users. It is disabled by default.
Theme-only baseline. Most apps should start here. Existing theme-only installations do not need a migration on upgrade to v0.2.0 — just re-run php artisan filament:assets so the refined surfaces, typography, navigation, tables, forms, and auth artwork are published.
Opt-in personalization. Enable ->customizer() only after confirming you want per-user appearance preferences. The included store is isolated by panel, guard, and user, so a user with access to multiple panels can have different appearances in each. Preferences apply immediately and can be reset from the customizer.
Restrict access first. The customizer is a profile action, so it is visible to signed-in panel users unless restricted. Use the authorization closure to gate it by role, permission, feature flag, or tenant policy:
MeUiPlugin::make()
->customizer()
// Wire the authorization closure and options as documented in
// docs/customization.md; restrict to users who should change appearance.
->customizerOptions([
'accent' => true,
'corners' => true,
'density' => true,
'contrast' => true,
// Disable controls that would break brand consistency.
]);
Curate the control allowlist. customizerOptions() is the main day-to-day lever: expose accent and density to everyone, but hide neutral palette, card treatment, or workspace layout if those are brand decisions. Pair the allowlist with developer defaults so every user starts from an approved baseline instead of the package default.
Use callbacks when you already have a preferences store. If your app already persists user settings (a JSON column, a settings table, tenant-scoped preferences), use the persistence callbacks instead of publishing the package migration. Treat the package as the UI and your store as the source of truth; validate and normalize values on save, and implement reset as an explicit write of the developer defaults.
Multi-panel and guard testing. Because preferences are isolated by panel and guard, verify appearance when switching panels, impersonating users, or using a separate guard for an admin area. A “theme reset” after switching panels is usually isolation working as intended, not a bug.
Deployment order. In CI/CD, run php artisan filament:assets during build (before the filesystem becomes read-only), then php artisan migrate only if you enabled the included store. Do not publish migrations on theme-only installations.
->customizer(); MeUiPlugin::make() alone is theme-only. Clear cached panel configuration after changing the provider.php artisan filament:assets is required after installing v0.2.0 and in deploy pipelines; stale published assets are a common cause of “the theme didn’t change.”php artisan optimize:clear, re-publish assets, verify the migration ran only when using the included store, and check the panel/guard/user key when preferences appear to be missing.customizerOptions() allowlist, persistence callbacks for your existing store, and the reset action. Prefer these over forking theme CSS.saivra/meui-theme and run your panel smoke tests on both SQLite and PostgreSQL if you support both.How can I help you explore Laravel packages today?