šŸ¦ā€šŸ”„ The Future of Web Development Why it may not be React or even Javascript at all

Mar 18, 2025

After five years of building React applications, I’ve spent the last six months exploring Phoenix LiveView. What I’ve found isn’t a silver bullet, but rather a fascinating alternative that challenges some of our assumptions about modern web development.

The Current Landscape

Most of us are familiar with the standard web stack: React (or similar) on the frontend, REST/GraphQL APIs, and separate backend services. This approach works - it’s battle-tested and has a massive ecosystem. But it also comes with complexity that we’ve perhaps too readily accepted as ā€œjust how things are.ā€

Consider the typical React application:

  • Complex state management libraries (Redux, Zustand, Jotai)
  • API layer with request/response handling, caching, and error states
  • Authentication tokens and refresh logic
  • Websocket connections managed separately from HTTP requests
  • Multiple build/bundle configurations
  • Hydration challenges with SSR
  • Complex deployment requirements for multiple services

We’ve normalized this complexity because it gives us flexibility and scale, but it’s worth asking: do all applications need this much infrastructure?

How LiveView Works

Before diving into comparisons, it’s important to understand LiveView’s technical approach. Unlike React’s client-side rendering with optional server components, LiveView takes a fundamentally different approach:

  1. Initial Page Load: The server renders HTML directly (no JavaScript bridge required)
  2. WebSocket Connection: Once loaded, the page establishes a WebSocket connection
  3. State Management: The server maintains a stateful process (via BEAM’s actor model) for each user session
  4. DOM Updates: Instead of sending JSON, LiveView sends minimal DOM patches over the WebSocket
  5. Client Interactivity: A small JavaScript library (~18KB) handles DOM updates and user events

Here’s what this looks like in practice:

defmodule CounterLive do
  use Phoenix.LiveView
  
  # State is maintained in this process
  def mount(_params, _session, socket) do
    {:ok, assign(socket, count: 0)}
  end

  # Events from the client are handled as messages
  def handle_event("increment", _params, socket) do
    {:noreply, update(socket, :count, &(&1 + 1))}
  end

  # The view is re-rendered on state changes
  def render(assigns) do
    ~H"""
    <div>
      <h1>Count: <%= @count %></h1>
      <button phx-click="increment">+</button>
    </div>
    """
  end
end

Compare this to a typical React setup:

// Client-side state management
const CounterContext = createContext()

// API layer
const updateCount = async (count) => {
  await fetch('/api/counter', {
    method: 'POST',
    body: JSON.stringify({ count })
  })
}

// Component with real-time updates
function Counter() {
  const [count, setCount] = useState(0)
  const socket = useSocket()
  
  useEffect(() => {
    socket.on('counter-update', setCount)
    return () => socket.off('counter-update')
  }, [])

  const increment = async () => {
    setCount(c => c + 1)
    await updateCount(count + 1)
  }

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>+</button>
    </div>
  )
}

Key Technical Differences

Let’s dive deeper into how LiveView fundamentally differs from React. These aren’t just implementation details - they represent fundamentally different approaches to building web applications. Understanding these differences is crucial for making informed decisions about when to use each technology.

1. State Management

  • React: State lives in the client, with optional server synchronization
  • LiveView: State lives in server-side processes, with the client as a view layer

2. Real-time Updates

  • React: Requires additional WebSocket setup, state sync logic, and error handling
  • LiveView: Built into the framework - the same programming model handles both regular requests and real-time updates

3. Network Traffic

  • React: Typically sends JSON payloads back and forth
  • LiveView: Sends minimal DOM diffs, reducing payload size for most operations

4. Error Handling

  • React: Must handle network errors, state inconsistencies, and retry logic explicitly
  • LiveView: Process supervision handles crashes, with automatic recovery and reconnection

5. Memory Usage

  • React: Memory usage primarily on client side
  • LiveView: Memory usage primarily on server side (about 0.5MB per active user session)

What LiveView Gets Right

The LiveView approach isn’t necessarily better, but it offers some interesting advantages:

  1. Simplified Mental Model: There’s no explicit state synchronization because the server owns the state. This isn’t always ideal, but for many features, it’s surprisingly liberating.

  2. Real-time Updates: WebSocket communication is built-in, not bolted on. This makes real-time features feel natural rather than exceptional.

  3. Progressive Enhancement: The basic functionality works without JavaScript, with interactivity layered on top. This isn’t always necessary, but it’s a nice fallback.

The Trade-offs

However, LiveView isn’t without its challenges:

  1. Latency Sensitivity: Every interaction goes to the server. While this works surprisingly well thanks to WebSocket connections, it’s not ideal for all scenarios.

  2. Learning Curve: Not just a new framework, but potentially a new language (Elixir) and runtime platform (BEAM). That’s a significant investment.

  3. Ecosystem: The JavaScript ecosystem is vast. While you can use JavaScript libraries with LiveView, it’s not as seamless as in a React application.

When to Consider LiveView

LiveView might be worth exploring if:

  • Real-time features are core to your application
  • You value server-side rendering
  • Your team can invest in learning new tools
  • Client-side state management is becoming unwieldy

Stick with React when:

  • You need sophisticated client-side interactions
  • Offline support is crucial
  • You’re heavily invested in JavaScript libraries
  • Latency is a major concern

Looking Forward

The web development landscape is evolving. While React and similar frameworks aren’t going anywhere, approaches like LiveView remind us to question our assumptions about how web applications should be built.

The future might not be choosing between client-side and server-side, but rather understanding the trade-offs well enough to pick the right tool for each job.

I’m still using React for many projects, but LiveView is something I am experimenting with and I am eager to try in a real-world project. It’s worth understanding even if you don’t end up using it - sometimes seeing a different approach helps us write better code, regardless of the tools we’re using.