emaia/laravel-hotwire
Composer 安装命令:
composer require emaia/laravel-hotwire
包简介
The complete Hotwire stack for Laravel — Turbo Drive, Turbo Streams, Stimulus controllers and Blade components out of the box.
README 文档
README
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
- Turbo
- Stimulus Controllers
- Stimulus Attribute Helpers
- Blade Components
- Verify Your Setup
- Configuration
- View Customization
- Extending
- Testing
- Manual Installation
- Changelog
- Contributing
- Security Vulnerabilities
- Credits
- License
Requirements
- PHP 8.3+
- Laravel 12+
- Stimulus with a loader compatible with
import.meta.glob( e.g. @emaia/stimulus-lazy-loader) - Tailwind CSS
- Vite.js
Installation
composer require emaia/laravel-hotwire
Publish the configuration file (optional):
php artisan vendor:publish --tag=hotwire-config
Quick Start
php artisan hotwire:install
This scaffolds the JS/CSS entry points, adds every npm dependency declared by the catalog to your package.json, wires
the @hotwire Vite alias into your vite.config.{ts,mjs,js}, generates the controller loader stub, runs your package
manager (auto-detected from the lockfile — bun/pnpm/yarn/npm), and verifies your views match the install config.
Components work out of the box — no controller publish step required.
For leaner installs (subset of catalog deps, --core-only), CI automation (--fix --no-interaction), the
auto-generated loader stub, drift detection, extending controllers and the full flag reference, see Advanced
installation.
Explore the Docs
You can browse the package docs directly in the terminal:
php artisan hotwire:docs
Interactive search, reading a single doc, and listing everything
This opens an interactive search across all controllers and components. Type a name, category, or keyword to filter:
┌ Search controllers and components ───────────────────────────────┐
│ form │
├───────────────────────────────────────────────────────────────────┤
│ auto-save [forms] Automatically saves a form… │
│ › auto-submit [forms] Submits a form automatically… │
│ clean-query-params [forms] Strips empty fields from the… │
│ optimistic--form [turbo] Dispatches optimistic UI… │
└───────────────────────────────────────────────────────────────────┘
Read a specific controller or component directly:
php artisan hotwire:docs auto-submit php artisan hotwire:docs turbo/progress php artisan hotwire:docs modal --component
List everything with category and description:
php artisan hotwire:docs --list php artisan hotwire:docs --list --controller php artisan hotwire:docs --list --component
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 helpers —
dom_id()anddom_class()for consistent element identification - Request detection —
wantsTurboStream()andwasFromTurboFrame()macros - Blade directives —
@turboNocache,@turboRefreshMethod('morph'), etc. - Testing utilities —
InteractsWithTurbotrait withassertTurboStream()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.
Stimulus Controllers (standalone)
Stimulus controllers without an associated Blade component. Used directly via data-controller and data-action.
Controllers live flat at the top level (resources/js/controllers/<name>_controller.{js,ts}). Substrate folders
(turbo/, optimistic/, dev/) group controllers tied to a specific technical layer and use Stimulus' -- separator
in the identifier.
php artisan hotwire:controllers auto-select auto-submit turbo/progress
Top-level controllers
| Controller | Identifier | Category | Dependencies | Docs |
|---|---|---|---|---|
| Accordion | accordion |
utility |
— | readme |
| Animated Number | animated-number |
utility |
— | readme |
| Auto Save | auto-save |
forms |
— | readme |
| Auto Resize | auto-resize |
forms |
— | readme |
| Auto Select | auto-select |
forms |
— | readme |
| Auto Submit | auto-submit |
forms |
— | readme |
| Autofocus | autofocus |
forms |
— | readme |
| Back to Top | back-to-top |
utility |
— | readme |
| Carousel | carousel |
utility |
embla-carousel |
readme |
| Char Counter | char-counter |
forms |
— | readme |
| Chart | chart |
utility |
echarts |
readme |
| Checkbox | checkbox |
forms |
— | readme |
| Checkbox Select All | checkbox-select-all |
forms |
— | readme |
| Clean Query Params | clean-query-params |
forms |
— | readme |
| Clear Input | clear-input |
forms |
— | readme |
| Conditional Fields | conditional-fields |
forms |
— | readme |
| Alert Dialog | alert-dialog |
overlay |
— | readme |
| Copy To Clipboard | copy-to-clipboard |
utility |
— | readme |
| Disclosure | disclosure |
utility |
— | readme |
| Dropdown | dropdown |
overlay |
@floating-ui/dom |
readme |
| Drawer | drawer |
overlay |
— | readme |
| Error Scroll | error-scroll |
forms |
— | readme |
| File Preserve | file-preserve |
forms |
— | readme |
| File Upload | file-upload |
forms |
@deltablot/dropzone |
readme |
| GTM | gtm |
utility |
— | readme |
| Hotkey | hotkey |
utility |
— | readme |
| Input Mask | input-mask |
forms |
maska |
readme |
| Lazy Image | lazy-image |
utility |
— | readme |
| Map | map |
utility |
leaflet |
readme |
| Modal | modal |
overlay |
— | readme |
| Modal Auto Close | modal-auto-close |
overlay |
— | readme |
| Multi Select | multi-select |
forms |
@floating-ui/dom |
readme |
| Money Input | money-input |
forms |
— | readme |
| OEmbed | oembed |
utility |
— | readme |
| Password Visibility | password-visibility |
forms |
— | readme |
| Remote Form | remote-form |
forms |
— | readme |
| Reset Files | reset-files |
forms |
— | readme |
| Rich Text | rich-text |
forms |
@tiptap/core, @tiptap/starter-kit, @tiptap/extension-placeholder, @tiptap/extension-link, @tiptap/extension-underline |
readme |
| Rich Text Toolbar | rich-text-toolbar |
forms |
— | readme |
| Scroll Progress | scroll-progress |
utility |
— | readme |
| Sheet | sheet |
overlay |
— | readme |
| Sidebar | sidebar |
utility |
— | readme |
| Slug | slug |
forms |
— | readme |
| Tabs | tabs |
utility |
— | readme |
| Timeago | timeago |
utility |
date-fns |
readme |
| Toast | toast |
feedback |
@emaia/sonner |
readme |
| Toaster | toaster |
feedback |
@emaia/sonner |
readme |
| Tooltip | tooltip |
utility |
tippy.js |
readme |
| Unsaved Changes | unsaved-changes |
forms |
— | readme |
Turbo
Controllers tied to Turbo Drive / Turbo Frames.
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Frame Src | turbo--frame-src |
@hotwired/turbo |
readme |
| Polling | turbo--polling |
@hotwired/turbo |
readme |
| Progress | turbo--progress |
@hotwired/turbo |
readme |
| View Transition | turbo--view-transition |
— | readme |
Optimistic
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Dispatch | optimistic--dispatch |
@hotwired/turbo |
readme |
| Form | optimistic--form |
@hotwired/turbo |
readme |
| Link | optimistic--link |
@hotwired/turbo |
readme |
Dev
| Controller | Identifier | Dependencies | Docs |
|---|---|---|---|
| Log | dev--log |
— | readme |
Publish Stimulus Controllers
Publish the controllers you want to use in your app so they can be discovered by the bundler (Vite).
Interactive — select which controllers to publish:
php artisan hotwire:controllers
By name — publish a specific controller:
php artisan hotwire:controllers auto-select
Substrate namespace — publish every controller under a substrate folder (turbo, optimistic, dev):
php artisan hotwire:controllers turbo
Multiple arguments — mix names and substrate namespaces:
php artisan hotwire:controllers modal turbo/progress auto-submit
All at once:
php artisan hotwire:controllers --all
List available controllers (with publication status):
php artisan hotwire:controllers --list
Update only controllers that are already published but differ from the package source:
php artisan hotwire:controllers --outdated
# Non-interactive — useful after composer update in CI or deploy scripts
php artisan hotwire:controllers --outdated --force
--outdated never installs controllers that haven't been published yet, and skips those that are already up to date.
Overwrite existing files:
php artisan hotwire:controllers auto-select --force
Top-level controllers are copied flat to resources/js/controllers/ (e.g. modal →
resources/js/controllers/modal_controller.js, identifier modal). Controllers under a substrate folder preserve
that folder and use Stimulus' -- separator (e.g. turbo/progress →
resources/js/controllers/turbo/progress_controller.js, identifier turbo--progress).
@emaia/stimulus-lazy-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.
Name collisions: package controller names are effectively reserved in
resources/js/controllers/. If you write your own controller whose file name matches a package one (e.g. your owntabs_controller.js), the tooling treats it as an outdated copy of the package controller —hotwire:controllers --force(or--outdated --force) andhotwire:check --fixwill overwrite it without prompting. Before naming a new controller, check the taken names withphp artisan hotwire:controllers --listand pick a different one.
Stimulus Attribute Helpers
Build Stimulus data-* attributes from Blade without hand-writing the verbose markup. The primary
stimulus() entry point returns a fluent, chainable builder that is Htmlable (renders directly in
{{ }}) and Arrayable (merges into a component's attribute bag):
<div {{ stimulus() ->controller('chart', ['name' => 'Likes', 'data' => [1, 2, 3, 4]]) ->action('chart', 'refresh', 'click') ->target('chart', 'canvas') }}>
stimulus(); stimulus_controller($name, $values = [], $classes = [], $outlets = []); stimulus_action($controller, $method, $event = null, $params = []); stimulus_target($controller, $target);
stimulus_controller() is an alias for stimulus()->controller(...); stimulus_action() and
stimulus_target() are shortcuts for stimulus()->action(...) and stimulus()->target(...).
See Stimulus attribute helpers for values/classes/outlets, action params, stacking multiple controllers, attribute-bag merging and the escaping rules.
Blade Components
| Component | Blade | Category | Stimulus Identifier(s) | Docs |
|---|---|---|---|---|
| Form | <hw:form> |
forms |
auto-submit, unsaved-changes, error-scroll, clean-query-params |
readme |
| Field | <hw:field> |
forms |
— | readme |
| Field Group | <hw:field.group> |
forms |
— | readme |
| Field Label | <hw:field.label> |
forms |
— | readme |
| Field Error | <hw:field.error> |
forms |
— | readme |
| Checkbox | <hw:checkbox> |
forms |
checkbox, auto-submit |
readme |
| Checkbox Group | <hw:checkbox-group> |
forms |
checkbox-select-all, auto-submit |
readme |
| Checkbox Group Item | <hw:checkbox-group.item> |
forms |
checkbox-select-all, auto-submit |
readme |
| Conditional Field | <hw:conditional-field> |
forms |
conditional-fields |
readme |
| File | <hw:file> |
forms |
file-preserve, reset-files |
readme |
| File Upload | <hw:file-upload> |
forms |
file-upload |
readme |
| Input | <hw:input> |
forms |
auto-select, clear-input, input-mask |
readme |
| Multi Select | <hw:multi-select> |
forms |
multi-select, clear-input |
readme |
| Rich Text | <hw:rich-text> |
forms |
rich-text, rich-text-toolbar |
readme |
| Select | <hw:select> |
forms |
— | readme |
| Switch | <hw:switch> |
forms |
auto-submit |
readme |
| Textarea | <hw:textarea> |
forms |
auto-resize, char-counter |
readme |
| Alert | <hw:alert> |
feedback |
— | readme |
| Flash Container | <hw:flash-container> |
feedback |
toaster |
readme |
| Flash Message | <hw:flash-message> |
feedback |
toast |
readme |
| Skeleton | <hw:skeleton> |
feedback |
— | readme |
| Spinner | <hw:spinner> |
feedback |
— | readme |
| Accordion | <hw:accordion> |
display |
accordion |
readme |
| Aspect Ratio | <hw:aspect-ratio> |
display |
— | readme |
| Avatar | <hw:avatar> |
display |
— | readme |
| Badge | <hw:badge> |
display |
— | readme |
| Breadcrumb | <hw:breadcrumb> |
display |
— | readme |
| Button Group | <hw:button-group> |
display |
— | readme |
| Card | <hw:card> |
display |
— | readme |
| Empty State | <hw:empty-state> |
display |
— | readme |
| Item | <hw:item> |
display |
— | readme |
| Kbd | <hw:kbd> |
display |
— | readme |
| Marker | <hw:marker> |
display |
— | readme |
| Pagination | <hw:pagination> |
display |
— | readme |
| Progress | <hw:progress> |
display |
— | readme |
| Separator | <hw:separator> |
display |
— | readme |
| Table | <hw:table> |
display |
— | readme |
| Tabs | <hw:tabs> |
display |
tabs |
readme |
| Alert Dialog | <hw:alert-dialog> |
overlay |
alert-dialog |
readme |
| Drawer | <hw:drawer> |
overlay |
drawer |
readme |
| Dropdown | <hw:dropdown> |
overlay |
dropdown |
readme |
| Modal | <hw:modal> |
overlay |
modal |
readme |
| Sheet | <hw:sheet> |
overlay |
sheet |
readme |
| Frame Or Page | <hw:frame-or-page> |
turbo |
— | readme |
| Optimistic | <hw:optimistic> |
turbo |
— | readme |
| Button | <hw:button> |
utility |
— | readme |
| Carousel | <hw:carousel> |
utility |
carousel |
readme |
| Chart | <hw:chart> |
utility |
chart |
readme |
| Icon | <hw:icon> |
utility |
— | readme |
| Map | <hw:map> |
utility |
map |
readme |
| Scroll Progress | <hw:scroll-progress> |
utility |
scroll-progress |
readme |
| Sidebar | <hw:sidebar> |
utility |
sidebar |
readme |
| Timeago | <hw:timeago> |
utility |
timeago |
readme |
Verify Your Setup
List components and their required controllers:
php artisan hotwire:components
Shows each Blade component, its tag, and the Stimulus controllers it depends on — with publication status for each.
Check controllers used in your views (components and direct usage):
php artisan hotwire:check
Scans resources/views for Hotwire components and direct Stimulus controller usage — data-controller
attributes and the stimulus_controller() / stimulus()->controller() / ->controllers() / stimulus_action() /
stimulus_target() helpers — then verifies two things:
- Stimulus controllers — every controller required by a used component, or referenced directly, is published and up to date.
- npm dependencies — every external package imported by those controllers (e.g.
@emaia/sonner,tippy.js) is declared in yourpackage.json(dependenciesordevDependencies).
Exits with code 1 if either has pending items (useful for CI).
Both the configured prefix (hw by default) and the short <hw:*> form are recognized, so views like
<hw:flash-message /> and <x-hw::flash-message /> are detected equally. Only controllers shipped by the package are
checked — your own controllers are ignored — and Blade comments and <script>/<style> blocks are stripped first, so
commented-out code is skipped.
# Auto-publish missing/outdated controllers AND add missing npm deps to devDependencies php artisan hotwire:check --fix # Also run the detected package manager install command after adding deps php artisan hotwire:check --fix --install # Scan a custom path php artisan hotwire:check --path=resources/views/app
Example output:
✓ toaster up to date (used by <hw:flash-container>)
✓ toast up to date (used by <hw:flash-message>)
Required npm dependencies:
✓ @emaia/sonner ^2.1.0 (used by toaster, toast)
✗ tippy.js ^6.3.7 missing from package.json (used by tooltip)
In interactive mode,
hotwire:checkasks whether to run the detected package manager install command after adding dependencies. In non-interactive scripts, use--fix --installto run it automatically.
Configuration
// config/hotwire.php return [ 'prefix' => 'hw', // <hw:modal> ];
Change prefix to use a different prefix for Blade components. E.g. 'prefix' => 'ui' → <ui:modal> or
<x-ui::modal>.
PhpStorm / Laravel Idea
The package ships ide.json metadata for Laravel Idea, so PhpStorm can complete and navigate <hw:*> components.
For Stimulus helper completions, generate an app-level ide.json:
php artisan hotwire:ide-json
hotwire:install runs this automatically for JS installs. The generated metadata includes package controllers and local
controllers from resources/js/controllers, with local controllers taking precedence when they override a package
identifier.
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.
Extending the package
Laravel Hotwire uses a single registry as the source of truth for:
- Blade components
- Stimulus controllers
- external npm dependencies
- docs paths
- public categories
When adding a new component or controller to this package, update the registry entry in
src/Registry/catalog.php.
Example component entry:
'modal' => [ 'class' => \Emaia\LaravelHotwire\Components\Modal::class, 'view' => 'hotwire::component-views.modal', 'docs' => 'docs/components/modal.md', 'category' => 'overlay', 'controllers' => ['modal'], ],
Example controller entry:
'tooltip' => [ 'source' => 'resources/js/controllers/tooltip_controller.js', 'docs' => 'docs/controllers/tooltip.md', 'category' => 'utility', 'npm' => ['tippy.js' => '^6.3.7'], ],
More details: docs/registry.md
Testing
composer test
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/libs/turbo.js import * as Turbo from "@hotwired/turbo"; export default Turbo; // resources/js/libs/stimulus.js import {Application} from '@hotwired/stimulus' const Stimulus = Application.start() window.Stimulus = Stimulus export {Stimulus} // resources/js/controllers/index.js import {Stimulus} from "../libs/stimulus"; import {registerControllers} from "@emaia/stimulus-lazy-loader"; const controllers = import.meta.glob("./**/*_controller.{js,ts}", { eager: false, }); registerControllers(Stimulus, controllers);
Install the required js dependencies:
bun add @hotwired/stimulus @hotwired/turbo @emaia/stimulus-lazy-loader
TailwindCSS (v4)
Add these settings to your CSS entrypoint resources/css/app.css:
@import "tailwindcss"; @import '../../vendor/emaia/laravel-hotwire/resources/css/presets/nova.css'; @source '../../vendor/emaia/laravel-hotwire/resources/css/**/*.css';
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Contributions are welcome via pull requests.
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.
emaia/laravel-hotwire 适用场景与选型建议
emaia/laravel-hotwire 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 77 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 10 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「turbo」 「stimulus」 「hotwire」 「emaia」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 emaia/laravel-hotwire 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 emaia/laravel-hotwire 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 emaia/laravel-hotwire 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Use Stimulus in your Laravel app
PHP5.4 Yandex Turbo Pages RSS feed generator
Turbocharge Laravel Nova by lazy loading resources. Dramatically improves performance for applications with 50+ resources.
TurboSMS HTTP API library, This package allows easy notification sending using [turbosms.ua](https://turbosms.ua). Optimized for php5.4 and above
Use Stimulus in your Laravel app
统计信息
- 总下载量: 77
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 36
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-10