Product Decisions This Supports
- Personalization / end-user theming as a shipped feature, not a bespoke build. Nitpick gives Filament panels a user-facing theme picker (user-menu item, dedicated Appearance page, or modal) with theme cards, colour swatches, and descriptions. The decision it unlocks is "do we offer theme choice at all?" — the answer is now cheap, so it becomes a scoping question rather than an engineering one.
- White-labeling and multi-brand delivery. Per-tenant or per-brand themes can be registered and selected without forking the panel. Themes can now carry their own panel configuration (top navigation, fonts, render hooks, colours, a styling plugin), which means a theme is a product surface, not just a colour palette — relevant if you sell branded deployments.
- Brand consistency versus user autonomy. The release explicitly moves plugin-backed themes to "reload and apply fully" rather than "preview half-applied." That is a deliberate product stance: correctness of the brand over smoothness of the preview. Worth ratifying as a product decision rather than treating as a technical footnote.
- Accessibility and polish commitments.
prefers-reduced-motion is honoured; transitions are optional and configurable (Fade default, Slide, Sweep, or false). This lets you make an accessibility claim without custom work.
- Dark/light mode correctness. Mode is now remembered per picked theme (and written under both
filament:theme:mode and legacy theme keys), so you can promise "your theme, your mode" across reloads — a common support-ticket source if done wrong.
- Build vs buy. A theme picker with transitions, modal layout, Octane safety, and asset publishing is 2–4 weeks of work you'd otherwise own forever. This is a non-differentiating surface; buying is the default answer unless theming is your product.
- Roadmap signal for 1.0.
->userSelectable() and ->appearancePage() are deprecated and removed in 1.0; ->picker() is the single entry point. Plan an API-migration line item now, not at 1.0.
When to Consider This Package
Consider it when:
- You run a Filament panel (v5-era; the notes explicitly track Filament 5.10.2 behaviour) and want user-selectable themes without building a picker.
- You need theme switching that survives real deployment conditions — the package restores the panel at request end, so Octane doesn't leak theme state between requests.
- You're doing white-label or per-brand panels and want themes to carry navigation, fonts, hooks, and a styling plugin.
- You want accessibility and reduced-motion handled out of the box, plus a small JS escape hatch (
window.PackstubThemes.pick() / PackstubThemes.reload()) for your own triggers.
- You can pin an exact beta version and absorb one migration when 1.0 lands.
Look elsewhere, or wait, when:
- You need a stable, semver-respecting 1.0 API today. This is
beta.2; the deprecations are already scheduled for removal, so expect churn.
- You are not on Filament, or are on a Filament version outside what the release notes test against.
- Your theming needs dynamic panel configuration that includes pages, resources, or widgets — those are explicitly not applied from a theme (routes exist before the request); they're skipped and reported. If your "theme" is really a module, this isn't the tool.
- Live, no-reload preview is a hard requirement for plugin-backed themes. They reload by design now.
- You only need dark mode — Filament already ships that; this is overkill.
- You require vendor SLA / multi-maintainer support. A beta from a single GitHub org should be treated as a dependency with exit cost; keep a fallback plan (a thin internal picker) in your back pocket.
How to Pitch It (Stakeholders)
To executives: This is a low-cost, high-visibility feature. For the price of a Composer dependency we can ship user-selectable themes, per-brand theming for white-label customers, correct dark/light persistence, and reduced-motion accessibility — work we'd otherwise build and maintain ourselves. The main caveat is maturity: it's a public beta, the API is still moving, and version 1.0 will require a small migration. Recommendation: adopt behind a feature flag on one panel, pin the version, and revisit at 1.0.
To engineering: It's a Filament plugin, not a framework change. Integration is a plugin registration plus ->picker() configuration; themes opt into panel configuration via Theme::make()->panel(...) or a ConfiguresPanel class. It's Octane-safe (panel is restored at request end), it publishes assets through the standard filament:assets / filament:upgrade pipeline, and it exposes a small JS API for custom triggers. Note two behaviour changes in this beta: a theme's styling plugin is now attached to the panel only while that theme is active — so it no longer leaks assets and render hooks onto every panel — and plugin-backed theme switches now reload the page rather than previewing live. Also note the deliberate limit: a theme cannot add pages, resources, or widgets, because routes are resolved before the request. Budget for the ->picker() migration now, since ->userSelectable() and ->appearancePage() are removed in 1.0.