Build LiveView: async data (assign_async), PubSub (check connected?), phx-change events, form components/modals/uploads, streams for lists, live_patch. Use when handling interactions, debugging events, or tracking Pre…
---
name: liveview-patterns
description: "Build LiveView: async data (assign_async), PubSub (check connected?), phx-change events, form components/modals/uploads, streams for lists, live_patch. Use when handling interactions, debugging events, or tracking Presence."
effort: medium
user-invocable: false
paths:
- "**/*_live.ex"
- "**/*_component.ex"
- "**/*.sface"
- "**/*_channel.ex"
---
# LiveView Patterns Reference
> **Ash projects**: Use `ash-framework` skill for `AshPhoenix.Form`. Lifecycle: `AshPhoenix.Form.validate/3` on `phx-change`, `AshPhoenix.Form.submit/2` on submit, `to_form/1` for HEEx. Do not use `Ecto.Changeset.cast/3`.
Reference for building with Phoenix LiveView 1.0/1.1.
## Iron Laws — Never Violate These
1. **NO UNCONDITIONAL DB QUERIES IN MOUNT** — Mount runs TWICE. Default: `assign_async`. SEO routes: `connected?` guard + cache-backed disconnected branch (crawlers read that HTML)
2. **ALWAYS USE STREAMS FOR LISTS** — Regular assigns = O(n) memory per user. Streams = O(1)
3. **CHECK connected?/1 BEFORE SUBSCRIPTIONS** — Prevents double subscriptions
4. **EXTRACT VARIABLES BEFORE assign_async CLOSURE** — Closures copy entire referenced variables
5. **LOAD PRIMARY DATA IN mount/3, PAGINATION IN handle_params/3** — handle_params runs on EVERY URL change… install to load the full skill