laravel-hotwire maintained by emaia
Laravel Hotwire
Blade components and Stimulus controllers for building interactive Laravel applications with Hotwire — no JavaScript framework required.
Requirements
- PHP 8.3+
- Laravel 12+
- Stimulus with a loader compatible with
import.meta.glob( e.g. @emaia/stimulus-dynamic-loader) - Tailwind CSS
- Vite.js
Installation
composer require emaia/laravel-hotwire
Publish the configuration file (optional):
php artisan vendor:publish --tag=hotwire-config
Stimulus Controllers
The components depend on Stimulus controllers that must be published to your project so they can be discovered by the bundler (Vite).
Interactive — select which controllers to publish:
php artisan hotwire:controllers
By namespace — publish all controllers in a namespace:
php artisan hotwire:controllers form
By specific controller — namespace/name notation:
php artisan hotwire:controllers form/autoselect
Multiple arguments — mix namespaces and specific controllers:
php artisan hotwire:controllers form dialog/modal
All at once:
php artisan hotwire:controllers --all
List available controllers (with publish status):
php artisan hotwire:controllers --list
Overwrite existing files:
php artisan hotwire:controllers form/autoselect --force
Controllers are copied to resources/js/controllers/ preserving the folder structure. The namespace/name argument
mirrors the directory structure: form/autoselect → resources/js/controllers/form/autoselect_controller.js.
The Stimulus identifier follows the same convention: dialog/modal → data-controller="dialog--modal".
@emaia/stimulus-dynamic-loader discovers and loads
them automatically via import.meta.glob.
If a controller already exists and is identical to the package version, the command reports it as up to date. If it differs, it asks for confirmation before overwriting.
List components and their required controllers:
php artisan hotwire:components
Shows each Blade component, its tag, and the Stimulus controllers it depends on — with publish status for each.
Check controllers for components used in your views:
php artisan hotwire:check
Scans resources/views for Hotwire components, checks whether their required Stimulus controllers are published, and
reports any missing or outdated ones. Exits with code 1 if attention is needed (useful for CI).
# Auto-publish missing/outdated controllers without prompting
php artisan hotwire:check --fix
# Scan a custom path
php artisan hotwire:check --path=resources/views/app
Project setup (using Vite)
// resources/js/app.js
import "./libs";
// resources/js/libs/index.js
import "./turbo";
import "./stimulus";
import "../controllers";
// resources/js/controllers/index.js
import {Stimulus} from "../libs/stimulus";
import {registerControllers} from "@emaia/stimulus-dynamic-loader";
const controllers = import.meta.glob("./**/*_controller.{js,ts}", {
eager: false,
});
registerControllers(Stimulus, controllers);
TailwindCSS (v4)
Add these settings to your CSS entrypoint /resources/css/app.css:
@source '../../vendor/emaia/laravel-hotwire/resources/views/**/*.blade.php';
@custom-variant turbo-frame (turbo-frame[src] &);
@custom-variant modal ([data-dialog--modal-target="dialog"] &);
@custom-variant aria-busy (form[aria-busy="true"] &);
@custom-variant self-aria-busy (html[aria-busy="true"] &);
@custom-variant turbo-frame-aria-busy (turbo-frame[aria-busy="true"] &);
View Customization
To customize the HTML/Tailwind of the components:
php artisan vendor:publish --tag=hotwire-views
Views published to resources/views/vendor/hotwire/ will take precedence over the package defaults.
Configuration
// config/hotwire.php
return [
'prefix' => 'hwc', // <x-hwc-modal>
];
Change prefix to use a different prefix for Blade components. E.g. 'prefix' => 'hotwire' → <x-hotwire-modal>.
Components
| Component | Blade | Stimulus Identifier | Docs |
|---|---|---|---|
| Modal | <x-hwc-modal> |
dialog--modal |
readme |
| Confirm Dialog | <x-hwc-confirm> |
dialog--confirm |
readme |
| Flash Message | <x-hwc-flash-message> |
notification--toaster, notification--toast |
readme |
| Loader | <x-hwc-loader> |
— | readme |
Stimulus Controllers (standalone)
Stimulus controllers without an associated Blade component. Used directly via data-controller and data-action.
php artisan hotwire:controllers form/autoselect form/autosubmit frame/progress
Dialog
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Modal | dialog--modal |
— | readme |
| Confirm | dialog--confirm |
— | readme |
Form
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Autoselect | form--autoselect |
— | readme |
| Autosubmit | form--autosubmit |
— | readme |
| Clean Querystring | form--clean-querystring |
— | readme |
| Clear Input | form--clear-input |
— | readme |
| Remote | form--remote |
— | readme |
| Reset Files | form--reset-files |
— | readme |
| Textarea Autogrow | form--textarea-autogrow |
— | readme |
| Unsaved Changes | form--unsaved-changes |
— | readme |
Frame
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Polling | frame--polling |
@hotwired/turbo |
readme |
| Progress | frame--progress |
@hotwired/turbo |
readme |
| View Transition | frame--view-transition |
— | readme |
Dev
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Log | dev--log |
— | readme |
Lib
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| GTM | lib--gtm |
— | readme |
| Maska | lib--maska |
maska |
readme |
| Tippy | lib--tippy |
tippy.js |
readme |
Media
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| OEmbed | media--oembed |
— | readme |
| Pending | media--pending |
— | readme |
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.