A standalone dark mode toggle component for Laravel with Light, Dark, and System modes,
localStorage persistence, optional server-side sync, and full CSS/frontend framework parity.
Every CSS and frontend combination is fully supported with identical features:
| Blade + Alpine.js | Livewire 3 | Vue 3 | React 18 | Svelte 4 | |
|---|---|---|---|---|---|
| Tailwind v4 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Bootstrap 5 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Bootstrap 4 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
15 combinations. Zero feature gaps.
composer require jeremykenedy/laravel-darkmode-toggle
php artisan darkmode:install
The interactive installer will prompt you to select your CSS and frontend frameworks.
php artisan darkmode:install --css=tailwind --frontend=blade
Note: If the package is already installed, the install command will warn you and recommend using
darkmode:updateinstead. You can force a fresh reinstall with--force, but this will overwrite your config and published views.
<head>Prevents flash of wrong theme on page load:
<head>
@include('darkmode::init-script')
</head>
Blade (with Alpine.js):
<x-darkmode-toggle />
Livewire:
<livewire:darkmode-toggle />
Vue:
<script setup>
import DarkmodeToggle from './vendor/darkmode-toggle/DarkmodeToggle.vue'
</script>
<template>
<DarkmodeToggle persist-url="/darkmode/preference" />
</template>
React:
import DarkmodeToggle from './vendor/darkmode-toggle/DarkmodeToggle'
export default function Nav() {
return <DarkmodeToggle persistUrl="/darkmode/preference" />
}
Svelte:
<script>
import DarkmodeToggle from './vendor/darkmode-toggle/DarkmodeToggle.svelte'
</script>
<DarkmodeToggle persistUrl="/darkmode/preference" />
localStorage, no page reload<head> before paintdark class on <html> elementconfig/darkmode.php and ENV variablesphp artisan vendor:publish --tag=darkmode-config
Key options in config/darkmode.php:
| Option | Default | Description |
|---|---|---|
strategy |
class |
Dark mode strategy |
class_name |
dark |
Class added to <html> |
default |
system |
Default mode (light/dark/system) |
storage_key |
theme |
localStorage key |
persist_to_server |
true |
Save to DB when authenticated |
persist_route |
/profile/dark-mode |
Server persistence endpoint |
persist_method |
PUT |
HTTP method for persistence |
persist_field |
dark_mode |
Request/DB field name |
css_framework |
null |
null = inherit from ui-kit.css_framework |
The package includes a route PUT /darkmode/preference that saves the preference to the user's profile. To use your own route:
'persist_route' => '/profile/dark-mode',
'routes' => ['enabled' => false],
The toggle sends a JSON request:
{ "dark_mode": "dark" }
After initial installation, use the update or switch commands to change your CSS or frontend framework without losing your configuration.
The update command shows the same stepped prompts as the installer, letting you walk through framework selection:
php artisan darkmode:update
Or pass options directly:
php artisan darkmode:update --css=bootstrap5
php artisan darkmode:update --frontend=vue
php artisan darkmode:update --css=tailwind --frontend=livewire
The switch command is a shorthand for changing one or both frameworks in a single command:
php artisan darkmode:switch --css=bootstrap5
php artisan darkmode:switch --frontend=livewire
php artisan darkmode:switch --css=tailwind --frontend=vue
Both commands update your .env file and clear the config/view caches. After switching, run:
npm run build
| Command | Description |
|---|---|
darkmode:install |
Fresh install with interactive prompts. Detects existing installation and warns before overwriting. |
darkmode:update |
Update framework selection with interactive prompts. Safe, does not overwrite config. |
darkmode:switch |
Quick framework switch via flags. --css and/or --frontend required. |
| Flag | Description |
|---|---|
--css= |
CSS framework: tailwind, bootstrap5, bootstrap4 |
--frontend= |
Frontend: blade, livewire, vue, react, svelte |
--force |
Skip reinstall confirmation when already installed |
<head>, reads localStorage, adds dark class before paintlocalStorage, toggles HTML class, optionally PUTs to serverprefers-color-scheme media query changes in real time./vendor/bin/pest --ci
This package is open-sourced software licensed under the MIT license.