Get AI summaries of any video or article — Sign up free
Jose Responds To Elixir LiveView Not Good Enough thumbnail

Jose Responds To Elixir LiveView Not Good Enough

The PrimeTime·
5 min read

Based on The PrimeTime's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Phoenix LiveView’s real-time model is built around coordinating server-rendered updates with client behavior rather than treating external DOM libraries as automatic disqualifiers.

Briefing

The central fight is over what counts as a “ceiling” for server-driven UI—especially Phoenix LiveView—and whether using client-side DOM libraries (like sortable drag-and-drop) undermines LiveView’s real-time promise. Jose Valim, creator of Elixir and the LiveView ecosystem, argues that modern web apps inevitably juggle both server state and client state, and that real-time UX only works when the framework treats those states as first-class concerns rather than pretending one side can be ignored.

The dispute starts with a long tweet thread claiming LiveView is “not good enough,” with examples of apps being “broken in seconds” and complaints that LiveView’s approach can be janky or fragile. The counterpoint is that LiveView’s model is designed for rich interactivity while keeping server-rendered HTML and real-time updates coordinated. In practice, the conversation narrows to a specific claim: if a UI interaction relies on external client-side DOM manipulation (for instance, drag-and-drop via SortableJS), that shouldn’t automatically be treated as a failure of LiveView. Instead, it can be the exact kind of “client-side behavior” LiveView is meant to support through integration points.

Jose’s article reframes the whole argument around state synchronization. Web pages can become stale immediately after render because other actors may change the underlying data—new comments, updated availability, or a user clicking “buy” before the server confirms success. That same mismatch appears even when only one user is involved: optimistic UI can show a “success” state that later gets corrected, and collaborative editing can create merge conflicts when multiple users change overlapping fields. The core message is that client-side state (even if it’s just input text) exists whether or not a framework encourages it, and large “client caches” that must stay in sync are a common source of bugs.

From there, the article defines “real time” as the server sending updates on a short cadence (seconds, not minutes) and stresses that real-time doesn’t mean blindly overriding what the user is doing. A collaborative editor might synchronize text instantly, but a category dropdown changing out from under a user can feel jarring unless the UI communicates what changed and why. LiveView’s approach is to keep a long-lived connection (a websocket “long pole”) and to control how updates are propagated and rendered so they remain cheap and performant.

To handle the tricky gap between what the client does immediately and what the server confirms later, LiveView uses an internal clock/sequence mechanism. When events are pushed to the server, LiveView tags updates with an always-increasing identifier; the client queues or applies server responses only when they match the most recent identifier, preventing “rollback” from older debounced events after a user submits. Jose positions this as a practical solution to a classic problem: inflight requests and out-of-order responses can otherwise undo UI state.

The discussion ends by broadening the lens: LiveView isn’t trying to eliminate JavaScript entirely, but to reduce the amount of custom client glue needed for production-grade real-time apps. Offline mode is acknowledged as a limitation, and the conversation also touches on performance tradeoffs (server-rendered HTML vs JSON) as context-dependent. The takeaway is less about winning a framework purity contest and more about whether the stack enables complex, multi-user, near-real-time experiences with fewer moving parts and fewer synchronization bugs.

Cornell Notes

The dispute over Phoenix LiveView centers on whether “server-driven” UI has a ceiling when real interactions require client-side DOM libraries. Jose Valim’s response reframes the issue: web apps always contain both server state and client state, and real-time UX only works when a framework treats both as first-class. LiveView keeps a websocket connection to coordinate server-rendered updates and uses a clock/sequence identifier to prevent stale, out-of-order server responses from rolling back newer client actions (e.g., debounced input followed by submit). The result is a model for rich, interactive, near-real-time applications without forcing developers to hand-build complex synchronization logic for every UI pattern.

Why does the “ceiling” argument about LiveView and external DOM libraries miss the point?

The transcript’s counterargument is that LiveView is designed to integrate client-side behavior when needed. Drag-and-drop is used as the example: SortableJS can drive the interaction, while LiveView provides the server coordination and update propagation. Calling that “bailing on LiveView” treats any DOM manipulation outside LiveView as a failure, but the practical question is whether the framework can still keep UI and server state synchronized without jank or broken flows.

What problem does Jose Valim identify as fundamental to web apps: server state or client state?

Both. Server state can change after render (new comments, updated availability), making the page stale. Client state also exists even without custom JavaScript—inputs and in-progress edits are client-only until the server confirms them. The transcript emphasizes that the hardest bugs often come from client-side caches that must sync with the server, so frameworks that ignore client state tend to create synchronization gaps.

How does the “clock” mechanism prevent UI rollback in LiveView?

In the email-validation example, a debounced change triggers a server event while the user continues typing and then submits. When the server later responds to the older debounced event, a naive client render could revert the form to a previous state. LiveView tags server pushes with an always-increasing identifier (a clock/sequence) and applies queued server changes only when the response matches the most recent identifier, so newer user intent isn’t overwritten by older inflight results.

Why doesn’t “real time” mean “override the user with the latest server data”?

The transcript uses a collaborative blog editor scenario: synchronizing text is helpful, but a dropdown category changing unexpectedly can feel wrong. Even if updates arrive quickly, the UI needs to explain or indicate changes so users aren’t surprised. Real-time systems must decide how updates are presented relative to what the user is currently doing, regardless of whether updates arrive as data (client-driven) or HTML chunks (server-driven).

What does LiveView’s websocket connection buy developers in real-time apps?

Because LiveView keeps a long-lived websocket connection, it can coordinate what the client has rendered and control how updates are propagated. That reduces the risk of overlapping updates with what the user is currently seeing or doing, and it enables LiveView to keep updates cheap and performant rather than forcing developers to manage all synchronization manually.

What limitations are acknowledged, and what does the stack still require?

Offline mode is called out as a major missing use case. Even with LiveView, some JavaScript integration is still expected for complex client behaviors. The transcript frames this as acceptable: the goal is to minimize custom client glue while still enabling multi-user, near-real-time features.

Review Questions

  1. In the email debounce + submit scenario, what specific failure mode does LiveView’s clock/sequence mechanism prevent?
  2. How does the transcript distinguish “real-time updates” from “overriding the user,” and what UI consequence is used to illustrate the difference?
  3. Why does the argument treat client-side state as unavoidable even in server-driven frameworks?

Key Points

  1. 1

    Phoenix LiveView’s real-time model is built around coordinating server-rendered updates with client behavior rather than treating external DOM libraries as automatic disqualifiers.

  2. 2

    Web apps inherently face staleness: server data can change immediately after render, and client-side in-progress state (like inputs) exists before the server confirms it.

  3. 3

    Ignoring client state leads to synchronization bugs, especially when client caches must stay consistent with server truth.

  4. 4

    Real-time UX requires thoughtful presentation of updates; fast synchronization doesn’t mean the UI should silently replace what the user is doing.

  5. 5

    LiveView’s clock/sequence identifier prevents older, out-of-order server responses (from debounced or inflight events) from rolling back newer user actions.

  6. 6

    LiveView uses a long-lived websocket connection to keep updates coordinated and performant, reducing overlap risks with what the user is currently viewing.

  7. 7

    Offline mode remains a notable limitation, and some JavaScript integration is still often necessary for complex interactions.

Highlights

The debate isn’t really about whether JavaScript exists—it’s about whether LiveView can keep UI and server state synchronized when client-side interactions are involved.
LiveView’s clock/sequence mechanism is presented as a concrete fix for a classic race condition: debounced server responses arriving after a user submits.
Real-time is framed as “near real time” (seconds) plus correct UX semantics—updates shouldn’t automatically override the user without explanation.
The transcript repeatedly returns to the same thesis: client state exists whether or not a framework encourages it, so state handling must be intrinsic to the solution.

Topics

  • Phoenix LiveView
  • State Synchronization
  • Real-Time UX
  • Client Hooks
  • Optimistic Updates

Mentioned