emaia/laravel-hotwire

The complete Hotwire stack for Laravel — Turbo Drive, Turbo Streams, Stimulus controllers and Blade components out of the box.

Maintainers

Package info

github.com/emaia/laravel-hotwire

pkg:composer/emaia/laravel-hotwire

Fund package maintenance!

emaia

Statistics

Installs: 7

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.7.3 2026-04-12 12:53 UTC

This package is auto-updated.

Last update: 2026-04-12 13:08:09 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Laravel Hotwire

The complete Hotwire stack for Laravel — Turbo Drive, Turbo Streams, Stimulus controllers and Blade components out of the box.

Table of Contents

Requirements

Installation

composer require emaia/laravel-hotwire

Publish the configuration file (optional):

php artisan vendor:publish --tag=hotwire-config

Quick Start

The install command scaffolds the Hotwire setup in your Laravel application — JS entry points, Stimulus loader, Turbo imports and CSS custom variants:

php artisan hotwire:install

This will:

  1. Copy JS and CSS scaffolding to resources/
  2. Add @hotwired/stimulus, @hotwired/turbo and @emaia/stimulus-dynamic-loader to your package.json
  3. Show instructions for the next steps

Options:

# Overwrite existing files without prompting
php artisan hotwire:install --force

# Install only JS or CSS scaffolding
php artisan hotwire:install --only=js
php artisan hotwire:install --only=css

If a target file already exists and is identical, it is skipped. If it differs, the command asks for confirmation before overwriting (unless --force is used).

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 controllernamespace/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/autoselectresources/js/controllers/form/autoselect_controller.js. The Stimulus identifier follows the same convention: dialog/modaldata-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

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.

Manual Installation

If you prefer to set things up manually instead of using hotwire:install, follow the steps below.

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);

Install the required js dependencies:

bun install @hotwired/stimulus @hotwired/turbo @emaia/stimulus-dynamic-loader

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"] &);

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>.

Turbo

This package includes emaia/laravel-hotwire-turbo as a dependency, providing full Turbo integration for Laravel:

  • Turbo Streams — fluent builder for append, prepend, replace, update, remove, morph, refresh and more
  • Turbo Frames<x-turbo::frame> Blade component with lazy loading support
  • DOM helpersdom_id() and dom_class() for consistent element identification
  • Request detectionwantsTurboStream() and wasFromTurboFrame() macros
  • Blade directives@turboNocache, @turboRefreshMethod('morph'), etc.
  • Testing utilitiesInteractsWithTurbo trait with assertTurboStream() assertions
// Example: return Turbo Streams
return turbo_stream()
    ->append('messages', view('messages.item', compact('message')))
    ->remove('modal');

See the full documentation at emaia/laravel-hotwire-turbo.

Components

Component Blade Stimulus Identifier Docs
Modal <x-hwc::modal> dialog--modal readme
Confirm Dialog <x-hwc::confirm-dialog> 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.