PHPackages                             r0073rr0r/laravel-theme-switcher - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. r0073rr0r/laravel-theme-switcher

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

r0073rr0r/laravel-theme-switcher
================================

Laravel Jestream Livewire Theme (Dark/Light mode) Switcher Component

v0.0.6(1mo ago)1211MITPHPPHP ^8.2CI passing

Since Mar 27Pushed 1mo agoCompare

[ Source](https://github.com/r0073rr0r/laravel-theme-switcher)[ Packagist](https://packagist.org/packages/r0073rr0r/laravel-theme-switcher)[ RSS](/packages/r0073rr0r-laravel-theme-switcher/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (6)Dependencies (16)Versions (7)Used By (0)

Laravel Theme Switcher
======================

[](#laravel-theme-switcher)

 A Laravel package for Jetstream and Livewire applications that provides a polished light, dark, and system theme switcher with persistence, package assets, and a Jetstream appearance form.

 [![Packagist Version](https://camo.githubusercontent.com/d5212a2d0ab32c11a27c6479e8ce0700acc66e37737ca5a41fe291f4e12be6c6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7230303733727230722f6c61726176656c2d7468656d652d7377697463686572)](https://packagist.org/packages/r0073rr0r/laravel-theme-switcher) [![Total Downloads](https://camo.githubusercontent.com/f9ed445f476b70f7d2f245013000411c7ef90af90ba49e98791f7be24c8bba63/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7230303733727230722f6c61726176656c2d7468656d652d7377697463686572)](https://packagist.org/packages/r0073rr0r/laravel-theme-switcher) [![PHP Version](https://camo.githubusercontent.com/9bd185193c3f7716697fd198d740c827786eebad97b0d15f11bcd88ff04421a5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7230303733727230722f6c61726176656c2d7468656d652d7377697463686572)](https://packagist.org/packages/r0073rr0r/laravel-theme-switcher) [![License](https://camo.githubusercontent.com/d954fbfab1b0faf3199703c9d193ec389b06c4f41789bbde95e9a9e02adaae2d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7230303733727230722f6c61726176656c2d7468656d652d7377697463686572)](https://packagist.org/packages/r0073rr0r/laravel-theme-switcher) [![Tests](https://github.com/r0073rr0r/laravel-theme-switcher/actions/workflows/tests.yml/badge.svg)](https://github.com/r0073rr0r/laravel-theme-switcher/actions/workflows/tests.yml) [![PHP Composer](https://github.com/r0073rr0r/laravel-theme-switcher/workflows/PHP%20Composer/badge.svg)](https://github.com/r0073rr0r/laravel-theme-switcher/actions/workflows/php.yml) [![GitHub Stars](https://camo.githubusercontent.com/a1324dcb17306a2263ec7aff6dfe9a7bac7a71c29fa05deaf783313d5ec58e82/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f7230303733727230722f6c61726176656c2d7468656d652d73776974636865723f7374796c653d736f6369616c)](https://github.com/r0073rr0r/laravel-theme-switcher/stargazers)

✨ Features
----------

[](#-features)

- 🌗 Reusable Livewire theme toggle with `light`, `dark`, and `system` modes
- 👤 Optional persistence through cookies and the authenticated user's `theme_preference`
- 🧩 Jetstream-ready appearance form component for profile settings
- 🎨 Publishable package views, translations, CSS, and JavaScript
- ⚡ Early `` bootstrap script to prevent theme flash before page paint
- 🛠️ Configurable toggle order, animations, tooltip behavior, sizing, and rounding

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Updating](#updating)
- [Setup](#setup)
- [Usage](#usage)
- [Theme Toggle](#theme-toggle)
- [Appearance Form](#appearance-form)
- [Translations](#translations)
- [Customization](#customization)
- [Notes](#notes)
- [License](#license)
- [Contributing](#contributing)

📋 Requirements
--------------

[](#-requirements)

- PHP 8.2+
- Laravel 12.x
- Livewire 3.x or 4.x
- Jetstream 5.x

🚀 Installation
--------------

[](#-installation)

Install the package via Composer:

```
composer require r0073rr0r/laravel-theme-switcher
```

Publish the package config:

```
php artisan vendor:publish --tag=theme-switcher
```

Publish the package views if you want to override them:

```
php artisan vendor:publish --tag=theme-switcher-views
```

Publish the package translations if you want to customize the text:

```
php artisan vendor:publish --tag=theme-switcher-translations
```

Publish the package CSS:

```
php artisan vendor:publish --tag=theme-switcher-css
```

Publish the package JavaScript:

```
php artisan vendor:publish --tag=theme-switcher-assets
```

Run the migration so the package can persist the user's `theme_preference` value on the `users` table:

```
php artisan migrate
```

🔄 Updating
----------

[](#-updating)

When updating the package, republish the resources you actually use so your application gets the latest views, translations, and frontend files:

```
composer update r0073rr0r/laravel-theme-switcher
php artisan vendor:publish --tag=theme-switcher-views --force
php artisan vendor:publish --tag=theme-switcher-translations --force
php artisan vendor:publish --tag=theme-switcher-css --force
php artisan vendor:publish --tag=theme-switcher-assets --force
```

If you have customized any published files, review the changes before overwriting them.

⚙️ Setup
--------

[](#️-setup)

### 1. Import the package CSS

[](#1-import-the-package-css)

Import the published stylesheet into your application's main stylesheet, for example in `resources/css/app.css`:

```
@import './vendor/theme-switcher.css';
```

If your application uses the package views directly, Tailwind also needs to scan them so utility classes such as `h-10`, `w-10`, and `rounded-full` are generated.

For Tailwind CSS v4, add this to `resources/css/app.css`:

```
@source "../../vendor/r0073rr0r/laravel-theme-switcher/resources/views/**/*.blade.php";
```

If you published the package views instead, point Tailwind to your published copies:

```
@source "../views/vendor/theme-switcher/**/*.blade.php";
```

For Tailwind CSS v3, add the same paths to the `content` array in `tailwind.config.js`.

### 2. Import the package JavaScript

[](#2-import-the-package-javascript)

Import the published JavaScript into your application's main JS entry file, for example in `resources/js/app.js`:

```
import './vendor/theme-switcher';
```

The package JavaScript expects a global theme manager at `window.masonTheme` with methods compatible with:

```
window.masonTheme.getResolvedTheme()
window.masonTheme.applyPreference(preference, { persist: true })
```

This keeps the Livewire component state synchronized with the browser theme state.

### 3. Add the startup script to your layout ``

[](#3-add-the-startup-script-to-your-layout-head)

To apply the theme before the page paints, add the package head component inside your main layout ``, for example in `resources/views/layouts/app.blade.php`:

```

```

This is the recommended integration point because it renders the inline startup script with the current server-side preference and updates the `dark` class before the UI flashes.

If you prefer a plain include instead of a Blade component, you can use:

```
@include('theme-switcher::components.head')
```

🧠 Configuration
---------------

[](#-configuration)

After publishing the package config, you can control the switcher's default behavior without editing package files:

```
return [
    'default_preference' => 'system',
    'allowed_preferences' => ['light', 'dark', 'system'],
    'cycle_order' => ['light', 'dark', 'system'],
    'animations' => [
        'enabled' => true,
        'duration' => 300,
        'icon_transition' => true,
        'hover_effects' => true,
        'respect_reduced_motion' => true,
    ],
    'persistence' => [
        'cookie_enabled' => true,
        'cookie_name_preference' => 'theme_preference',
        'cookie_name_theme' => 'theme',
        'cookie_minutes' => 60 * 24 * 365,
        'database_enabled' => true,
    ],
    'ui' => [
        'show_system_option' => true,
        'button_size' => 'md',
        'rounded' => 'full',
        'show_tooltip' => true,
    ],
    'events' => [
        'dispatch_theme_changed' => true,
        'dispatch_preference_updated' => true,
    ],
];
```

What these options are for:

- `default_preference`: fallback preference when no authenticated or cookie state exists.
- `allowed_preferences`: restrict the package to `light`, `dark`, or `system`.
- `cycle_order`: controls the order used by the header toggle button.
- `animations.*`: enables or disables hover and icon transitions, with reduced-motion support.
- `persistence.*`: decides whether the package writes cookies, updates the authenticated user, or both.
- `ui.*`: controls whether `system` is shown, the button size, shape, and tooltip behavior.
- `events.*`: lets you disable the package browser events if you want to manage sync manually.

Examples:

- `['light', 'dark']` removes the system option from the toggle and the profile appearance form.
- Setting `animations.enabled` to `false` renders the same UI without motion transitions.
- Setting `persistence.database_enabled` to `false` keeps the switcher cookie-based only.

🧪 Usage
-------

[](#-usage)

### Theme Toggle

[](#theme-toggle)

Render the Livewire component wherever you want the theme toggle button:

```

```

Or:

```
@livewire('theme-switcher')
```

The component:

- Reads the current theme preference from the authenticated user when available
- Falls back to cookies when no authenticated preference exists
- Cycles through the preferences defined in `theme-switcher.cycle_order`
- Persists the selected preference according to the `persistence` config
- Updates the authenticated user's `theme_preference` column when database persistence is enabled

### Appearance Form

[](#appearance-form)

The package also registers a Livewire component alias for Jetstream profile settings:

```
@livewire('profile.update-appearance-form')
```

If you want to show it on the default Jetstream profile page, open:

```
resources/views/profile/show.blade.php

```

Then add this block near the top of the main content area, for example after the profile information form:

```

    @livewire('profile.update-appearance-form')

```

If you prefer to reference the class directly, you can also use:

```
@livewire(\r0073rr0r\ThemeSwitcher\Livewire\Profile\UpdateAppearanceForm::class)
```

The form view rendered by that component comes from the package:

```
resources/views/profile/update-appearance-form.blade.php

```

If you publish the package views, you can override that file and adapt it to your own account settings flow.

🌍 Translations
--------------

[](#-translations)

The package loads its own translations automatically through the `theme-switcher` namespace, so publishing translations is optional.

Example keys:

```
__('theme-switcher::theme-switcher.appearance')
__('theme-switcher::theme-switcher.save')
```

How translation fallback works:

- If the application does not publish translations, Laravel uses the package translation files directly
- If translations are published, Laravel will prefer `lang/vendor/theme-switcher`
- If the current locale does not exist, Laravel will try the application's `fallback_locale`

This package already includes:

- `resources/lang/en/theme-switcher.php`
- `resources/lang/sr/theme-switcher.php`

That means a typical application with `fallback_locale=en` will still show English text even when the active locale has no dedicated theme-switcher translation yet.

🎨 Customization
---------------

[](#-customization)

After publishing, you can customize these package resources:

- Views: `resources/views/vendor/theme-switcher`
- Translations: `lang/vendor/theme-switcher`
- CSS: `resources/css/vendor/theme-switcher.css`
- JavaScript: `resources/js/vendor/theme-switcher.js`

The startup head script is provided by the package view component:

- Component: `theme-switcher::components.head`
- Include/partial: `theme-switcher::components.head`

📝 Notes
-------

[](#-notes)

- The package CSS is intended to be included in the consumer application's build pipeline
- The package JavaScript is intended to be imported into the consumer application's JS entry file
- The startup head script should be rendered from Blade, not bundled as a plain JavaScript file, because it depends on server-side preference state
- The package no longer publishes unrelated third-party assets
- The authenticated user model is expected to support a `theme_preference` column if you want per-user persistence
- The service provider registers both `theme-switcher` and `profile.update-appearance-form` Livewire aliases
- When `animations.respect_reduced_motion` is enabled, motion utility classes are reduced for users who prefer less animation

✅ Testing
---------

[](#-testing)

The package test suite is written with Pest and covers configuration helpers, Livewire components, head bootstrap rendering, and persistence behavior.

Run the tests locally with:

```
php vendor/bin/pest
```

📄 License
---------

[](#-license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

🤝 Contributing
--------------

[](#-contributing)

Pull requests are welcome. For larger changes, open an issue first so the scope is clear before implementation.

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance91

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~9 days

Total

6

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9ebbcd8b937d006e91b7ac7c2f3942f11cf86e0f7f6d7d9d40d0256021d0f905?d=identicon)[r00terr0r](/maintainers/r00terr0r)

---

Top Contributors

[![r0073rr0r](https://avatars.githubusercontent.com/u/11500982?v=4)](https://github.com/r0073rr0r "r0073rr0r (9 commits)")

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/r0073rr0r-laravel-theme-switcher/health.svg)

```
[![Health](https://phpackages.com/badges/r0073rr0r-laravel-theme-switcher/health.svg)](https://phpackages.com/packages/r0073rr0r-laravel-theme-switcher)
```

###  Alternatives

[nasirkhan/laravel-starter

A CMS like modular Laravel starter project.

1.4k2.7k](/packages/nasirkhan-laravel-starter)[ramonrietdijk/livewire-tables

Dynamic tables for models with Laravel Livewire

21255.6k](/packages/ramonrietdijk-livewire-tables)[lakm/laravel-comments

Integrate seamless commenting functionality into your Laravel project.

40614.3k1](/packages/lakm-laravel-comments)[team-nifty-gmbh/tall-datatables

Server-side rendered datatables for Laravel and Livewire

1319.7k3](/packages/team-nifty-gmbh-tall-datatables)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.2k](/packages/tomshaw-electricgrid)[marcorieser/statamic-livewire

A Laravel Livewire integration for Statamic.

23100.9k12](/packages/marcorieser-statamic-livewire)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
