facuz/laravel-themes
A Laravel package for adding multi-theme support to your app. Organize theme views, assets, translations, and configuration, switch the active theme at runtime, and use theme-aware Blade helpers without changing your core application structure.
Architecture fit. facuz/laravel-themes is a thin orchestration layer over Laravel's view subsystem. It registers a service provider, extends the framework's view finder to resolve templates from a theme directory, and exposes a Theme facade for set(), find(), asset(), and render helpers. A "theme" is essentially a convention: one directory holding views/, assets/, lang/, and partials. That fits Laravel's service-container idiom cleanly and introduces no exotic dependencies.
The caveat is that it extends one of the more brittle seams in the framework. Overriding the view finder puts the package in the resolution path for every view(), @include, and Blade component lookup, which is exactly where Laravel's internals shift between majors.
Integration feasibility. Mechanically easy: composer require, auto-discovered provider, publish config, drop in a theme folder, call Theme::set(). A one-day spike should produce a working themed page. The real effort is retrofitting existing views and asset() calls and establishing directory conventions — that's an adoption cost, not an integration cost.
Technical risk. This is a community continuation of teepluss/theme, which has been effectively unmaintained since the Laravel 5 era. The significant risks:
illuminate/support constraint and CI matrix before anything else. View-finder contracts and the asset pipeline (Mix → Vite) have moved substantially; a package that predates Vite likely assumes publish-to-public/ assets.Key questions for the maintainer or a spike: Which Laravel/PHP versions are tested in CI? Does it support Vite manifest assets or only legacy publishing? Does it compose with Blade components and view namespaces? What is the stated upgrade path for future Laravel majors? Is there a documented exit to native view namespaces?
Verdict: viable for a contained, low-blast-radius use case behind an internal abstraction; not viable as an unexamined dependency in a core rendering path.
Stack fit. Strongest for Blade-rendered Laravel apps with genuine multi-theme needs — white-labeling, per-tenant branding, or a CMS-managed front end. Poor fit for Inertia/SPA front ends, where theming belongs in the JS build, or for apps that only need a light/dark toggle.
Migration path. Near drop-in from teepluss/theme (namespace change), but treat it as a new dependency with its own risk profile rather than a fork upgrade. Critically, do not let controllers and Blade templates call the facade directly. Introduce an internal ThemeManager interface with set(), current(), asset(), and render(), and bind the package behind it. This costs perhaps two days and buys a clean exit ramp to Laravel's native view()->addNamespace() plus config-driven view resolution — which covers the majority of real theming use cases without the dependency at all.
Compatibility. Pin the exact version. Confirm PHP 8.x and the targeted Laravel version in composer.json. Check for conflicts with anything else that touches the view layer (debug toolbars, SEO/meta packages, view caching layers). Add a CI job that runs the app's smoke tests against the pinned package and the next Laravel minor so upgrades surface early.
Sequencing.
Maintenance. Budget for owning a vendored fork if the package becomes load-bearing. Single maintainer, low activity, and a legacy lineage mean upstream fixes may not arrive. Assign a named owner and a quarterly review of upstream commits and open issues; a stale dependency in the view layer is a latent upgrade blocker for the whole app.
Support. Community-only, no SLA. Your team is the de facto support organization, and debugging view-resolution issues requires framework internals knowledge that is unevenly distributed.
Scaling. Runtime overhead is negligible — extra path resolution and cached compiled views. The scaling cost is operational: every theme multiplies view paths, asset bundles, and publish steps. In a multi-tenant model, theme count and tenant count compound, and the deploy pipeline must publish and cache-bust assets per theme. This is manageable but must be designed before the second theme exists, not after the tenth.
Failure modes to instrument.
View [x] not found after a theme switch or cache clear — usually a stale config or missing fallback.view:clear a mandatory deploy step.Ramp-up. Low for Blade-fluent developers — hours to productivity. The hidden cost is the resolution rules: fallback order between theme views and application views, precedence for namespaced views, and asset path conventions. Document these in a one-page runbook and back them with a smoke test, or the second and third developer on the project will spend days rediscovering them during incidents.
How can I help you explore Laravel packages today?