packstub/filament-nitpick
packstub/filament-nitpick is a small Filament plugin for Laravel that brings nitpick-style checks into your admin panel workflow. Lightweight and quick to install, it suits teams wanting fast feedback without leaving Filament.
Architecture fit
packstub/filament-nitpick is a Filament panel plugin (Laravel/PHP) that layers runtime theme switching onto a Filament 5.x application. Architecturally it sits in the panel-configuration phase: it mutates the Panel object per request, registers a user-menu entry and/or Appearance page, and persists the selection. This release deepens that coupling deliberately — themes can now configure the panel directly (Theme::make()->panel(fn (Panel $panel) => ...), or a ConfiguresPanel theme class) and can attach their own Filament plugin while active (Theme::make()->plugin()). That is the right shape for a multi-theme product: theme behaviour travels with the theme rather than being re-declared by the host app.
The important structural constraint is now explicit: pages, resources and widgets added via the panel callback are not applied, because their routes are resolved before the request. Nitpick reports them instead of silently dropping them. This confirms themes are a presentation-layer concern only — if your product roadmap includes per-theme routes or navigation shapes, that is out of scope and needs a different mechanism.
Integration feasibility
Integration is a composer install plus NitpickPlugin::make() on the panel, then defining themes. The public surface has consolidated nicely in this release: ->picker(fn (ThemePicker $picker) => ..., condition:, modal:, userMenuItem:, page:, transition:) is a single entry point with additive semantics (omitted options retain earlier values), and there is a documented theme-author path (docs/theme-authors.md) plus a convention for auto-joining the picker when both packages are present. For teams consuming third-party Filament themes rather than authoring their own, this is close to drop-in.
Technical risk
userSelectable() / appearancePage() (and their getters) are deprecated in this release and removed in 1.0. Any code written against beta.1 needs touching. Budget for one more breaking pass at 1.0 GA.plugin(). Themes that previously relied on getStylesheets() / getColors() returning a bundled plugin's assets will now get neither; the plugin is instead mounted on the panel only while active. This is a correctness improvement (assets and global render hooks no longer leak onto every panel and every theme) but it is a silent-ish change for anyone who consumed those methods.filament:theme:mode, dual-written with legacy theme), which tells you the framework's own persistence contract moves under this package. Assume further churn across Filament minors.backdrop-filter/filter/transform from the topbar while a modal is open — a workaround aimed at one specific theme (Mia). Expect a class of CSS-interaction bugs that are theme-specific and hard to generalise.Key questions
userSelectable() / appearancePage() — is 1.0 imminent or a quarter out?condition:) in a way that composes with our existing authorisation model?prefers-reduced-motion — keyboard traversal of the modal, focus return, contrast of swatches?Stack fit
Assumes a Filament 5.x panel on Laravel with Livewire; Tailwind-built theme plugins are explicitly supported without extra build steps, and filament:assets / filament:upgrade still publish plugin files. If your application is a single-panel admin, fit is high. Multi-panel or multi-tenant installs need a review of which panel the picker attaches to and whether theme selection is global or per-panel — the release notes do not settle this.
Migration path
Greenfield: define themes, enable ->picker(), choose a Transition (Fade is the default; Transition::Sweep/Slide/false are options), and register the Appearance page only if you want a full-page surface. Brownfield from beta.1: replace ->userSelectable() / ->appearancePage() with ->picker(userMenuItem: ..., page: ...) now rather than at 1.0; audit any theme that reads getStylesheets() / getColors() for plugin assets, and move those themes to Theme::make()->plugin() or ConfiguresPanel depending on whether you want live preview (panel callback) or plugin fidelity (plugin, with reload).
Compatibility
Filament 5.10.2+ is the well-supported path for mode persistence; earlier 5.x works via the dual-written theme key. Octane is accounted for. Compatibility with non-Filament-panel surfaces (front-end, marketing site) is out of scope. Any custom theme with its own CSS transitions should be tested against the cover/reveal sequence — Nitpick holds panel CSS transitions during the reveal, which can visibly delay intentional animations.
Sequencing
descriptions(), swatches(false), columns([...])).window.PackstubThemes.pick() JS API only if you need programmatic switching; note the { reload: true } + PackstubThemes.reload() contract for scripted picks.Maintenance Low-to-moderate ongoing cost, front-loaded. The package owns the hard parts (panel restoration, transition orchestration, mode keys). Your maintenance burden is theme authoring plus tracking Filament minors. The deprecation cadence is the main signal: a beta that removes APIs at 1.0 will require a coordinated upgrade, so pin exact versions and treat theme definitions as code under review.
Support
Support load will concentrate in three predictable areas: (a) "my theme reloaded the page" — correct behaviour for plugin themes, needs a documented explanation and ideally a UI hint; (b) theme-specific CSS breakage (the Mia/backdrop-filter class of bug); (c) light/dark mode expectations, now that the switcher marks the mode the picked theme applies rather than the mode the page loaded with — arguably more correct but a behaviour change users will notice. Publish an internal FAQ before rollout.
Scaling Runtime cost is negligible for live switching. Reload-based picks cost a full page load and a re-bootstrap of Livewire plus lazy widgets, which the cover waits on (capped at 2.5 s). For large panels with heavy widgets, a theme switch becomes a multi-second operation — acceptable as a rare action, poor if users flip themes often or if themes are used for A/B presentation. Rapid re-picking is handled gracefully (the newer theme applies under the same cover), so no thundering-herd of reloads.
Failure modes
Ramp-up
A competent Laravel/Filament engineer can ship a first theme in a day; the docs/theme-authors.md authoring guide materially shortens the path for teams building their own themes. The conceptual load is the panel-callback vs. plugin split and its live-preview/reload consequence — this should be the first thing in your internal runbook, because it determines which of the two authoring models each theme must use.
How can I help you explore Laravel packages today?