From laraclaude
Audits Livewire/Volt components for unserializable properties, missing wire:key, orphaned events, and re-render issues. Run report for diagnostics or fix with auto-repair.
How this skill is triggered — by the user, by Claude, or both
Slash command
/laraclaude:livewire-audit [report | fix | fix --dry-run | file-path | fix file-path][report | fix | fix --dry-run | file-path | fix file-path]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Subcommand | Description |
| Subcommand | Description |
|---|---|
report | Scan all Volt components and report issues without making changes |
fix | Scan all Volt components, report issues, and auto-fix what is safe to fix |
fix --dry-run | Show what fixes would be applied without writing changes |
<file-path> | Scan a single file and report issues |
fix <file-path> | Scan a single file and auto-fix issues |
This skill audits Livewire/Volt components for common bugs, anti-patterns, and runtime errors. It targets issues that cause serialization failures, DOM diffing bugs, broken event wiring, and silent rendering problems.
Parse the argument to decide what to scan:
report: Scan all .blade.php files under resources/views/livewire/ that contain Volt component signatures (new class extends Component).fix (no path): Same scope as report but apply fixes.fix --dry-run: Same scope as fix but only show proposed changes.<file-path>: Scan only the specified file.fix <file-path>: Scan and fix only the specified file.Use Glob to find files:
resources/views/livewire/**/*.blade.php
Filter to only files containing Volt component PHP blocks (look for new class extends Component).
For every file in scope, check the following rules in order:
Livewire can only serialize: primitives (string, int, float, bool, null, array), Eloquent Models, Eloquent Collections, Carbon instances, Stringable, and Enums.
Pattern to detect: Public properties with type hints or assignments that are objects NOT in the safe list.
Look for:
public SomeClass $prop where SomeClass is not a Model, Collection, Carbon, BackedEnum, or Stringable$this->prop = new SomeObject() in mount/methods where $prop is public and SomeObject is not safeReport format:
[UNSERIALIZABLE] file.blade.php:42
Public property `$fieldConfig` has type `FieldConfig` which cannot be serialized by Livewire.
Suggestion: Make it protected and use a getter method, or convert to array.
Fix: No auto-fix (requires manual refactoring). Report only.
Pattern to detect: @foreach loops that contain <livewire: or @livewire( tags without a wire:key or :wire:key attribute.
Look for blocks like:
@foreach($items as $item)
<livewire:some-component :model="$item" />
@endforeach
Where the <livewire: tag does NOT have wire:key="..." or :wire:key="...".
Also check for @foreach loops containing <div> or other elements wrapping Livewire components without wire:key on either the wrapper or the component.
Report format:
[MISSING-WIRE-KEY] file.blade.php:87
@foreach loop renders <livewire:card> without wire:key.
This causes DOM diffing bugs when items are reordered or removed.
Fix: Add wire:key="{{ $loop->index }}" to the Livewire component tag. Prefer using a unique model identifier if available (e.g., wire:key="component-{{ $item->id }}").
Pattern to detect: wire:model="fieldName" or wire:model.live="fieldName" in the blade section where fieldName (or the root property if dot notation) is not declared as a public property in the PHP block.
Parse the PHP class block to extract all public property names. Then scan the blade template for wire:model bindings and check each root property name exists.
Handle dot notation: wire:model="data.name" means the root property is $data.
Report format:
[MISSING-PROPERTY] file.blade.php:123
wire:model="clientName" but no public property `$clientName` found in component.
Fix: No auto-fix (the developer must decide the property type and default). Report only.
Pattern to detect: $this->dispatch('event-name') or $dispatch('event-name') where no component in the project has a matching #[On('event-name')] listener.
Exclude well-known framework events: close-modal, open-modal, close-drawer, open-drawer, notify, toast, refresh.
Search across ALL Volt components (not just the current file) for #[On('event-name')] attributes.
Report format:
[ORPHANED-EVENT] file.blade.php:56
Dispatches 'property-updated' but no component has #[On('property-updated')] listener.
Fix: No auto-fix. Report only.
Pattern to detect: Elements with id attributes that are referenced by JavaScript (document.getElementById, document.querySelector('#id')) inside or alongside the component, where the parent does not have wire:ignore.
Also detect: Elements inside <x-modal> or drawer components that are populated by JavaScript event listeners (look for addEventListener patterns that set textContent, innerHTML, or value).
Report format:
[MISSING-WIRE-IGNORE] file.blade.php:145
Element #eventTitle is updated by JavaScript but not inside a wire:ignore block.
Livewire will reset this content on re-render.
Fix: Wrap the affected elements in a <div wire:ignore> container.
Pattern to detect: wire:model.live="prop" where the component has methods triggered by that property update (e.g., updated hooks, computed properties that query the database, or the property is used in a query inside render()).
Also flag: multiple wire:model.live bindings in the same form (each keystroke on any field = full server roundtrip).
Report format:
[MISSING-DEBOUNCE] file.blade.php:78
wire:model.live="search" triggers server request on every keystroke.
Consider wire:model.live.debounce.300ms="search".
Fix: Replace wire:model.live="prop" with wire:model.live.debounce.300ms="prop".
Pattern to detect: <a href="..."> tags pointing to internal routes (containing route('...') or relative paths starting with /) that do NOT have wire:navigate attribute.
Exclude: links with target="_blank", links to external URLs, anchor links (#), links to file downloads, links already having wire:navigate.
Only flag this in files that use an SPA layout (check if the layout extends a layout with @livewireScripts or uses wire:navigate elsewhere).
Report format:
[MISSING-WIRE-NAVIGATE] file.blade.php:34
Internal link <a href="{{ route('properties.index') }}"> missing wire:navigate.
Fix: Add wire:navigate attribute to the <a> tag.
Pattern to detect: Public properties typed as \Illuminate\Database\Eloquent\Collection or \Illuminate\Support\Collection, or assigned from ->get(), ->all(), or Collection::make().
Large collections as public properties increase payload size on every Livewire request.
Report format:
[COLLECTION-PROPERTY] file.blade.php:15
Public property `$users` is an Eloquent Collection. Consider using ->toArray(),
a computed property, or pagination to reduce payload size.
Fix: No auto-fix. Report only with suggestion.
Pattern to detect: $this->redirect('http...', navigate: true) or $this->redirectRoute('...', navigate: true) where the URL is an external domain.
Report format:
[BAD-REDIRECT] file.blade.php:67
$this->redirect() with navigate:true to external URL will fail.
Remove navigate:true for external redirects.
Fix: Remove navigate: true from the redirect call.
Group findings by file, then by severity:
Severity levels:
Output format:
## Livewire Audit Report
### resources/views/livewire/calendar.blade.php
- [ERROR] Line 42: Unserializable public property `$fieldConfig` (FieldConfig)
- [WARNING] Line 87: @foreach renders <livewire:card> without wire:key
- [INFO] Line 78: wire:model.live="search" should use debounce
### resources/views/livewire/properties/index.blade.php
- [WARNING] Line 34: Internal link missing wire:navigate
---
**Summary**: 2 errors, 2 warnings, 1 info across 2 files.
For fix or fix <file-path>:
For fix --dry-run:
Safe auto-fixes (applied automatically):
wire:key to Livewire components in loopsdebounce.300ms to wire:model.livewire:navigate to internal linksnavigate: true from external redirectswire:ignoreUnsafe fixes (report only, never auto-fix):
npx claudepluginhub edulazaro/laraclaude --plugin laraclaudeScans Livewire/Volt components for performance anti-patterns: render-time queries, excessive public properties, and unnecessary reactivity. Caught slow page loads, large payloads, and needless re-renders.
Builds reactive UI with Livewire 4 on Laravel 13 using wire:model, actions, events, Volt, and Folio without writing JavaScript.
Creates interactive server-driven UI components in WordPress Sage themes using Livewire v3 via Acorn. Handles wire:model, file uploads, computed properties, and real-time form validation without writing JavaScript.