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 pageReal-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