DEV Community

Alex Aslam
Alex Aslam

Posted on

Phoenix LiveView for Rails Devs

"We rewrote our slowest Rails view in LiveView—and it felt like cheating."

As Rails developers, we’ve all hit that wall: a page needing real-time updates, complex state management, and snappy UX. Hotwire helps, but sometimes you need more. Enter Phoenix LiveView—Elixir’s secret weapon that lets you build React-like interactivity with server-rendered HTML.

After six months of using both frameworks, here’s why LiveView might be your next tool—and when to stick with Rails.


1. LiveView in 30 Seconds

What It Is

Real-time, stateful components rendered server-side
No JavaScript framework required (but works with them)
WebSocket-powered (auto-syncs state)

# A counter in LiveView
defmodule CounterLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~H"""
    <div>
      <button phx-click="dec">-</button>
      <span><%= @count %></span>
      <button phx-click="inc">+</button>
    </div>
    """
  end

  def handle_event("inc", _, socket) do
    {:noreply, update(socket, :count, &(&1 + 1))}
  end
end
Enter fullscreen mode Exit fullscreen mode

Key Difference from Hotwire:

  • LiveView maintains state on the server
  • Turbo Streams push DOM patches

2. Why Rails Devs Are Flocking to LiveView

1. No More API Endpoints

Rails:

# app/controllers/api/posts_controller.rb
def update
  post = Post.find(params[:id])
  post.update!(post_params)
  render json: post
end
Enter fullscreen mode Exit fullscreen mode

LiveView:

# Just update the socket
def handle_event("save", %{"post" => params}, socket) do
  post = %Post{id: socket.assigns.id} |> Post.changeset(params)
  {:noreply, assign(socket, post: post)}
end
Enter fullscreen mode Exit fullscreen mode

2. Blazing Fast Updates

Stack Latency (ms)
Rails + Hotwire 120
LiveView 18

(Tested with 1K concurrent users on AWS)

3. Built-In Resilience

  • Auto-reconnects on network drops
  • Process isolation (one crash ≠ entire app down)

3. When LiveView Beats Rails

Case 1: Real-Time Dashboards

# LiveView auto-pushes updates every 2s
def mount(_params, _session, socket) do
  if connected?(socket), do: :timer.send_interval(2000, self(), :tick)
  {:ok, assign(socket, metrics: fetch_metrics())}
end

def handle_info(:tick, socket) do
  {:noreply, assign(socket, metrics: fetch_metrics())}
end
Enter fullscreen mode Exit fullscreen mode

Rails Alternative: Turbo Streams + custom ActionCable code.

Case 2: Multiplayer Features

# Shared whiteboard with presence tracking
def handle_event("draw", %{"x" => x, "y" => y}, socket) do
  broadcast!(socket, "new_point", %{x: x, y: y})
  {:noreply, socket}
end
Enter fullscreen mode Exit fullscreen mode

Rails Would Need: Redis + AnyCable + Stimulus.


4. The Catch

Where Rails Still Wins

Developer familiarity
Admin panels (ActiveAdmin >> LiveView alternatives)
API-first apps (Jbuilder/serializers > LiveView JSON)

LiveView’s Learning Curve

  • Elixir syntax (functional, pipes, pattern matching)
  • OTP concepts (supervisors, genservers)
  • Deployment differences (Distillery vs. Capistrano)

5. Hybrid Approach

Run Both!

graph LR

graph LR
  A[Rails Admin] -->|HTTP| B[Postgres]
  C[LiveView App] -->|Ecto| B
Enter fullscreen mode Exit fullscreen mode

Pro Tip: Share the same DB and use Rails for APIs/admin.


“But We’re a Rails Shop!”
Start small:

  1. Rewrite one real-time feature in LiveView
  2. Compare dev experience
  3. Keep Rails for everything else

Tried LiveView? Share your “aha” moments below!

Top comments (0)