livewire
Grounded stack guidance: pull idiomatic Blade/UI Do/Don't + docs URLs
via ./scripts-run <skills-root>/corpus-grounding/scripts/ground search --manifest <skills-root>/design-intelligence/data/manifest.json --stack laravel "<topic>" (UI-scoped corpus). See
design-intelligence.
Positioning — dispatched, not standalone
livewire is the apply-step executor for the Livewire stack. It is
invoked by directives/ui/apply.ts
once the design brief is locked, and revisited by review.ts /
polish.ts during the design-review loop. It does not own the
flow, does not drive the audit, and does not lock the design.
When to use
Cite this skill when:
state.stack.frontend == "livewire" and directives/ui/apply.ts dispatches to this skill
- Editing or creating Livewire components — reactive state, forms, tables, real-time updates
Do NOT use when:
- Static Blade views with no interactivity (use
blade-ui skill)
- Flux UI primitives (use
flux skill — livewire composes Flux internally)
- Driving the full UI flow yourself — that is the
directives/ui/ orchestrator
Procedure: Create a Livewire component
Step 0: Inspect
- Detect Livewire version —
composer.json for livewire/livewire.
- v3:
#[Layout], #[Title], property attributes.
- v2:
$layout, $listeners, method-based hooks.
- Check existing components —
app/Livewire/ or app/Http/Livewire/.
- Check views —
resources/views/livewire/.
Step 1: Create component class
declare(strict_types=1), final class.
- Typed public properties for state — keep minimal.
#[Locked] for tamper-proof properties.
#[Url] for URL-synced properties.
Step 2: Implement actions
- Public methods callable from frontend.
- Validate before processing:
$this->validate().
$this->dispatch() for cross-component communication (v3).
Step 3: Create view
- One root element (
<div>).
wire:key on dynamic lists.
wire:loading for user feedback.
wire:model.live for real-time updates (v3 default is deferred).
Step 4: Test
Livewire::test(ComponentClass::class)
->set(), ->call(), ->assertSee(), ->assertHasNoErrors()
Conventions
→ See guideline php/livewire.md for state management, forms, performance, Alpine.js, templates.
Output format
- Livewire component class with typed properties and actions
- Blade view with wire: bindings and Flux components
Review pass — a11y findings + preview envelope
When this skill is dispatched by directives/ui/review.ts (test slot)
or directives/ui/polish.ts (verify slot) — i.e. a review/polish run,
not the initial apply — it also emits:
state.ui_review.a11y — {violations: [{rule, selector, severity}, ...], severity_floor?, accepted_violations?}. Use the same (rule, selector)
shape as state.ui_audit.a11y_baseline so the engine's de-dup matches
pre-existing entries on replay. Omit the envelope on apply passes; the
engine's _apply_a11y_gate only fires when a baseline is present.
state.ui_review.preview — {render_ok: bool, screenshot_path?, dom_dump_path?, error?, skipped?}. render_ok: false with error
populated triggers the preview_render_failed halt; render_ok: true
with screenshot_path threads the screenshot into the delivery
report's artifacts list. Browser tooling (Playwright/Cypress/…) is
a consumer-project dependency — this package does not ship one.
Polish dispatch: when the dispatcher skips review because a previous
review pass already returned SUCCESS, this skill MUST itself
synthesise the updated state.ui_review.findings (including any
remaining a11y_violation entries) so the engine's gate sees the
current state on the next polish round.
Gotcha
- Public properties serialize between requests — don't put large objects in state.
wire:model is deferred by default in v3 — use wire:model.live for real-time.
$this->redirect() + $this->dispatch() in same method — only redirect executes.
Do NOT
- Do NOT put heavy computation in
render() — it runs on every update.
- Do NOT nest Livewire components deeply — keep the tree shallow.
- Do NOT expose sensitive data as public properties.
Anti-slop
When a Livewire component renders UI, pull
docs/guidelines/design-antipatterns.md
for the Visual / Layout / Motion checks (loading states that animate layout
properties — M2 — are a common Livewire wire:loading pitfall). Stack styling
bans: tailwind-engineer.
Auto-trigger keywords
- Livewire
- reactive component
- wire:model
- lifecycle
- real-time UI
1---2name: livewire3description: Use when the project's frontend stack is Livewire — dispatched by `directives/ui/{apply,review,polish}.ts`. Covers reactive state, events, lifecycle hooks, and component/view separation.4---56# livewire78> **Grounded stack guidance:** pull idiomatic Blade/UI Do/Don't + docs URLs9> via `./scripts-run <skills-root>/corpus-grounding/scripts/ground search10> --manifest <skills-root>/design-intelligence/data/manifest.json11> --stack laravel "<topic>"` (UI-scoped corpus). See12> [`design-intelligence`](../design-intelligence/SKILL.md).1314## Positioning — dispatched, not standalone1516`livewire` is the **apply-step executor** for the Livewire stack. It is17invoked by [`directives/ui/apply.ts`](../../templates/scripts/work_engine/directives/ui/apply.ts)18once the design brief is locked, and revisited by `review.ts` /19`polish.ts` during the design-review loop. It does **not** own the20flow, does **not** drive the audit, and does **not** lock the design.2122| Concern | Owner |23|---|---|24| Audit + token inventory (mandatory pre-step) | [`existing-ui-audit`](../existing-ui-audit/SKILL.md) |25| Design brief (layout / states / microcopy) | [`directives/ui/design.ts`](../../templates/scripts/work_engine/directives/ui/design.ts) |26| Universal design heuristics | [`fe-design`](../fe-design/SKILL.md) |27| Static Blade partials inside the view | [`blade-ui`](../blade-ui/SKILL.md) |28| Flux primitives inside the view | [`flux`](../flux/SKILL.md) |2930## When to use3132Cite this skill when:3334- `state.stack.frontend == "livewire"` and `directives/ui/apply.ts` dispatches to this skill35- Editing or creating Livewire components — reactive state, forms, tables, real-time updates3637Do NOT use when:3839- Static Blade views with no interactivity (use `blade-ui` skill)40- Flux UI primitives (use `flux` skill — `livewire` composes Flux internally)41- Driving the full UI flow yourself — that is the `directives/ui/` orchestrator4243## Procedure: Create a Livewire component4445### Step 0: Inspect46471. Detect Livewire version — `composer.json` for `livewire/livewire`.48 - v3: `#[Layout]`, `#[Title]`, property attributes.49 - v2: `$layout`, `$listeners`, method-based hooks.502. Check existing components — `app/Livewire/` or `app/Http/Livewire/`.513. Check views — `resources/views/livewire/`.5253### Step 1: Create component class54551. `declare(strict_types=1)`, `final` class.562. Typed public properties for state — keep minimal.573. `#[Locked]` for tamper-proof properties.584. `#[Url]` for URL-synced properties.5960### Step 2: Implement actions61621. Public methods callable from frontend.632. Validate before processing: `$this->validate()`.643. `$this->dispatch()` for cross-component communication (v3).6566### Step 3: Create view67681. One root element (`<div>`).692. `wire:key` on dynamic lists.703. `wire:loading` for user feedback.714. `wire:model.live` for real-time updates (v3 default is deferred).7273### Step 4: Test7475- `Livewire::test(ComponentClass::class)`76- `->set()`, `->call()`, `->assertSee()`, `->assertHasNoErrors()`7778## Conventions7980→ See guideline `php/livewire.md` for state management, forms, performance, Alpine.js, templates.8182## Output format83841. Livewire component class with typed properties and actions852. Blade view with wire: bindings and Flux components8687### Review pass — a11y findings + preview envelope8889When this skill is dispatched by `directives/ui/review.ts` (test slot)90or `directives/ui/polish.ts` (verify slot) — i.e. a review/polish run,91not the initial apply — it also emits:9293- `state.ui_review.a11y` — `{violations: [{rule, selector, severity}, ...],94 severity_floor?, accepted_violations?}`. Use the same `(rule, selector)`95 shape as `state.ui_audit.a11y_baseline` so the engine's de-dup matches96 pre-existing entries on replay. Omit the envelope on apply passes; the97 engine's `_apply_a11y_gate` only fires when a baseline is present.98- `state.ui_review.preview` — `{render_ok: bool, screenshot_path?,99 dom_dump_path?, error?, skipped?}`. `render_ok: false` with `error`100 populated triggers the `preview_render_failed` halt; `render_ok: true`101 with `screenshot_path` threads the screenshot into the delivery102 report's `artifacts` list. Browser tooling (Playwright/Cypress/…) is103 a consumer-project dependency — this package does not ship one.104105Polish dispatch: when the dispatcher skips `review` because a previous106review pass already returned `SUCCESS`, this skill MUST itself107synthesise the updated `state.ui_review.findings` (including any108remaining `a11y_violation` entries) so the engine's gate sees the109current state on the next polish round.110111## Gotcha112113- Public properties serialize between requests — don't put large objects in state.114- `wire:model` is deferred by default in v3 — use `wire:model.live` for real-time.115- `$this->redirect()` + `$this->dispatch()` in same method — only redirect executes.116117## Do NOT118119- Do NOT put heavy computation in `render()` — it runs on every update.120- Do NOT nest Livewire components deeply — keep the tree shallow.121- Do NOT expose sensitive data as public properties.122123## Anti-slop124125When a Livewire component renders UI, pull126[`docs/guidelines/design-antipatterns.md`](../../../docs/guidelines/design-antipatterns.md)127for the Visual / Layout / Motion checks (loading states that animate layout128properties — M2 — are a common Livewire `wire:loading` pitfall). Stack styling129bans: [`tailwind-engineer`](../tailwind-engineer/SKILL.md).130131## Auto-trigger keywords132133- Livewire134- reactive component135- wire:model136- lifecycle137- real-time UI