liveview-patterns

LiveView Patterns Reference

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "liveview-patterns" with this command: npx skills add oliver-kriska/claude-elixir-phoenix/oliver-kriska-claude-elixir-phoenix-liveview-patterns

LiveView Patterns Reference

Reference for building with Phoenix LiveView 1.0/1.1.

Iron Laws — Never Violate These

  • NO DATABASE QUERIES IN DISCONNECTED MOUNT — Queries run TWICE (HTTP + WebSocket). Use assign_async

  • ALWAYS USE STREAMS FOR LISTS — Regular assigns = O(n) memory per user. Streams = O(1)

  • CHECK connected?/1 BEFORE SUBSCRIPTIONS — Prevents double subscriptions

  • EXTRACT VARIABLES BEFORE assign_async CLOSURE — Closures copy entire referenced variables

  • LOAD PRIMARY DATA IN mount/3, PAGINATION IN handle_params/3 — handle_params runs on EVERY URL change

  • NEVER PASS SOCKET TO BUSINESS LOGIC — Extract data before calling contexts

  • CHECK CHANGESET ERRORS BEFORE UI DEBUGGING — Silent form save = check {:error, changeset} first, not viewport/JS

  • HIDDEN INPUTS FOR ALL REQUIRED EMBEDDED FIELDS — Every required field in an embedded schema MUST have a hidden_input if not directly editable

  • NEVER USE assign_new FOR LIFECYCLE VALUES — assign_new skips the function if key exists. Use assign/3 for locale, current user, or any value refreshed every mount

Memory Impact

Pattern 3K items 10K users × 10K items

Regular assigns ~5.1 MB ~10+ GB

Streams ~1.1 MB Minimal (O(1))

Decision: Lists with >100 items → Use streams, not assigns

Quick Patterns

Async Assigns (CRITICAL)

def mount(%{"slug" => slug}, _session, socket) do

Extract needed values BEFORE the closure

scope = socket.assigns.current_scope

{:ok, socket |> assign_async(:org, fn -> {:ok, %{org: fetch_org(scope, slug)}} end)} end

Streams for Lists

def mount(_params, _session, socket) do {:ok, stream(socket, :items, Items.list_items())} end

Insert/update/delete

stream_insert(socket, :items, item, at: 0) stream_delete(socket, :items, item)

PubSub with connected? check

def mount(_params, _session, socket) do if connected?(socket), do: Chat.subscribe(room_id) {:ok, socket} end

Navigation Decision Tree

Same LiveView, different params? → patch / push_patch Different LiveView, same live_session? → navigate / push_navigate Different live_session or non-LiveView? → href / redirect

Component Decision Tree

Does component need BOTH internal state AND event handling? │ ├── YES → Does it encapsulate APPLICATION logic (not just DOM)? │ ├── YES → Use LiveComponent ✅ │ └── NO → Refactor to function component with parent handling │ └── NO → Use Function Component ✅

Official guidance: "Prefer function components over live components"

Common Anti-patterns

Wrong Right

DB queries without assign_async

Use assign_async for all queries

assign(socket, items: list) for lists stream(socket, :items, list)

PubSub subscribe without connected?

if connected?(socket), do: subscribe()

Passing socket to context functions Extract socket.assigns first

Business logic in handle_event

Delegate to context

assign_new for locale/user in hooks assign/3 (must run every mount)

References

For detailed patterns, see:

  • references/async-streams.md

  • assign_async, stream_async, streams

  • references/forms-uploads.md

  • Forms, validation, file uploads

  • references/components.md

  • Function components, LiveComponents

  • references/pubsub-navigation.md

  • PubSub, navigation, JS commands

  • references/js-interop.md

  • Third-party JS libraries, phx-update="ignore", hooks

  • references/channels-presence.md

  • Phoenix Channels, Presence, token auth

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

oban

No summary provided by upstream source.

Repository SourceNeeds Review
General

ecto-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

tidewave-integration

No summary provided by upstream source.

Repository SourceNeeds Review
General

phx:full

No summary provided by upstream source.

Repository SourceNeeds Review