Turbo
02 / 02

Turbo: Streams, Real-Time Updates & Hotwire

Turbo: Streams, Real-Time Updates & Hotwire

Turbo Streams

<turbo-stream action="append" target="messages">
  <template>
    <div id="message_42">New message text</div>
  </template>
</turbo-stream>

<!-- Describes one targeted DOM operation: append, prepend,
     replace, remove, or update -- delivered via a form
     response or pushed over a WebSocket -->

Responding to a Turbo-Aware Request

def create
  @message = Message.create!(message_params)

  respond_to do |format|
    format.turbo_stream  # renders create.turbo_stream.erb
    format.html { redirect_to messages_path }
  end
end

# Turbo-aware form submissions send an Accept header the
# server can branch on, returning a stream or a full page

Real-Time Broadcasts Over WebSockets

Broadcasting a Turbo Stream over a WebSocket (e.g. via Action Cable in Rails) lets the server push a targeted DOM update -- a new chat message, for example -- to every connected client in real time, applied automatically with no custom client-side rendering code needed.

Turbo + Stimulus = Hotwire

Turbo handles navigation and fragment updates; Stimulus is a minimal framework for the custom JavaScript behavior that's still occasionally needed. Together they aim to reduce -- not eliminate -- the total custom JavaScript surface area of an application.

When a Client-Side Framework Fits Better

For features needing rich, purely-client-side interaction with minimal server round-trips -- a complex drag-and-drop editor, for instance -- a client-side framework's local state management can be a more natural fit than Turbo's server-round-trip-oriented model.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free