jonnifyelixir
F6 · Phoenix Framework / F6.06 · liveview

F6 · the architecture · module 6

Phoenix LiveView fundamentals

Everything so far has been one stateless round trip: a request arrives, a controller builds a response, HEEx renders it, the connection closes. LiveView changes the shape. A LiveView is a stateful server process connected to the browser over a WebSocket — an OTP process, the same kind of long-lived, message-driven actor the F5 engine was built from. It holds socket assigns as its state, renders the same HEEx from F6.05 as a function of those assigns, and when state changes it re-renders and pushes only the diff down the wire. The lifecycle is small and regular: mount/3 sets the initial state, render/1 produces markup, handle_event/3 turns a browser event into new state, and the loop continues. You write no JavaScript for the common interactions — a search box, a button, a live-updating list — because the server holds the state and the client only applies diffs. The same contexts from F6.04 still supply the data; LiveView adds the statefulness and the live connection on top of the view you already have.

Three dives: mounting a LiveView and its socket assigns, handling events to update state, and how render diffs reach the browser — the interactive layer over the same HEEx and contexts.

One turn of the live loop

loop mount/3 assign(socket, count: 0) render/1 ~H project assigns to HEEx handle_event/3 "inc" → update(count, &(&1 + 1)) diff ↔ socket only the changed value travels SOCKET ASSIGNS @count = 0 RENDERED HEEx Clicked 0 PHASE mount/3 step 1 / 4

mount/3 — @count = 0, rendered as "Clicked 0"
Advance once to walk the cursor; a click reaches handle_event, bumps the assign, and only the diff returns.

Three parts of the loop

A LiveView is a tight lifecycle, and this module takes each part in turn. mount/3 sets the socket’s initial state. handle_event/3 updates that state when the browser sends an event. render/1 turns state into HEEx, and LiveView ships only what changed. Select a part.

The LiveView loop · select a part

mount/3 set the socket's initial state — assigns from the facade F6.06.1 handle_event/3 update state on a browser event — {:noreply, socket} F6.06.2 render/1 HEEx from assigns — only the diff is pushed over the socket F6.06.3

callback: mount/3

does: set the socket's initial state

It is the same shape as a GenServer from F5: initial state, then messages that return new state. A LiveView is that pattern with a browser on the other end and HEEx as the projection of its state.

From request to process

The shift is from a thing that happens once to a thing that stays alive. A controller request (F6.01) runs, responds, and is gone — stateless by design. A LiveView mounts a process that lives for the duration of the page, holds state, and exchanges small messages with the client. The first paint is still plain HTML over HTTP (so it is fast and indexable); then the socket connects and the process takes over.

Stateless request vs stateful LiveView

CONTROLLER (F6.01) — stateless request → response connection closes — nothing persists each interaction is a new request LIVEVIEW — stateful process 1. disconnected HTTP render (first paint) 2. socket connects — process holds state mount → render → events → re-render diffs ↔ browser, over the wire the page stays live until the socket drops

Because the state lives in a server process, an event does not re-run a whole request — it sends a message, the process updates its assigns, and the client receives a small diff. That is the entire reason LiveView feels instant without a single line of front-end state management.

Three deep dives

In order: mounting a LiveView and its socket assigns; handling browser events into new state; and how render produces diffs that travel the socket.

F6.06.1
mount & assigns
The socket as process state, mount/3, the two-stage connect, and connected?/1 for side effects.
F6.06.2
handle_event & state
phx-click, phx-change, phx-submit into handle_event/3, a live search box, and a live create form.
F6.06.3
render & diffs
Change tracking on the HEEx static/dynamic split, the diff over the wire, and streams for large collections.

F5 gave us

OTP processes — stateful actors that hold state and respond to messages.

LiveView is

that actor with a browser attached and HEEx as its rendered state.

Start with mount and assigns, then handle_event and state, then render and diffs. This module follows F6.05 — HEEx — whose templates it now renders live, and the next, F6.07, adds PubSub so many LiveViews update at once.

References

The LiveView programming model, its callbacks, bindings, and change tracking.

Sources

Related in this course