Turbo Frames and Turbo Streams
Turbo Frames and Turbo Streams are sub-components of Hotwire that enable partial page updates and real-time server-pushed changes without full page reloads.
Table of Contents
What are Turbo Frames and Turbo Streams in Ruby on Rails?
Turbo is part of the Hotwire toolkit introduced in Rails 7 and included by default in Rails 7 and 8. It replaces the need for custom JavaScript in most cases by letting the server drive page updates directly through HTML.
Turbo Frames allow specific sections of a page to be updated independently. When a link or form is inside a Turbo Frame, only that frame's content is replaced on response, leaving the rest of the page untouched.
Turbo Streams go further by allowing the server to send multiple targeted updates to different parts of a page in a single response, or push updates to connected clients in real time over WebSockets using Action Cable.
Together, they cover two distinct needs: Turbo Frames for scoped, request-response updates, and Turbo Streams for broadcasting changes to one or many clients.
Why Are Turbo Frames and Turbo Streams Useful?
Full page reloads create a poor user experience for interactive applications. Turbo Frames and Turbo Streams help by:
-
Updating only the relevant part of a page without a full reload
-
Reducing the need to write custom JavaScript for common UI interactions
-
Enabling real-time updates pushed from the server to connected clients
-
Keeping server-rendered HTML as the single source of truth
-
Simplifying the development of interactive features without a frontend framework
-
Working with standard Rails controllers, views, and partials
They are especially useful for live feeds, inline editing, notifications, comment sections, and any feature that benefits from partial or real-time updates.
How Do Turbo Frames and Turbo Streams Work?
Key components:
turbo-frame tag – Wraps a section of the page that can be independently updated
Turbo Stream actions – Server responses that target specific DOM elements using actions like append, prepend, replace, update, and remove
.turbo_stream.erb templates – View templates that return Turbo Stream responses instead of full HTML pages
Action Cable integration – Allows Turbo Streams to be broadcast to multiple clients over WebSockets in real time
turbo_stream_from helper – Subscribes a page to a broadcast channel for live updates
Examples
Scenario 1: Turbo Frames - Inline Comment Form
A page where submitting a comment updates only the comments section without reloading the full page.
View (app/views/posts/show.html.erb)
<%= turbo_frame_tag "comments" do %> <%= render @comments %> <%= form_with model: [@post, Comment.new] do |f| %> <%= f.text_area :body %> <%= f.submit "Add Comment" %> <% end %> <% end %>
Controller (app/controllers/comments_controller.rb)
def create @comment = @post.comments.create!(comment_params) @comments = @post.comments end
View (app/views/comments/create.html.erb)
<%= turbo_frame_tag "comments" do %> <%= render @comments %> <%= form_with model: [@post, Comment.new] do |f| %> <%= f.text_area :body %> <%= f.submit "Add Comment" %> <% end %> <% end %>
When the form is submitted, Rails responds with the updated frame content. Only the comments section refreshes, the rest of the page is untouched.
Scenario 2: Turbo Streams - Appending a New Comment in Real Time
Instead of replacing the entire frame, Turbo Streams can append just the new comment to the list.
Controller
def create @comment = @post.comments.create!(comment_params) respond_to do |format| format.turbo_stream format.html { redirect_to @post } end end
Turbo Stream template (app/views/comments/create.turbo_stream.erb)
<%= turbo_stream.append "comments", @comment %>
This appends only the new comment to the comments container on the page, without touching anything else.
Scenario 3: Turbo Streams - Broadcasting Real-Time Updates via Action Cable
Turbo Streams can push updates to all connected clients in real time using Action Cable.
Model (app/models/comment.rb)
class Comment < ApplicationRecord belongs_to :post after_create_commit -> { broadcast_append_to @post, target: "comments" } end
View (app/views/posts/show.html.erb)
<%= turbo_stream_from @post %> <div id="comments"> <%= render @post.comments %> </div>
When a new comment is created, it is automatically broadcast and appended to the comments section for every connected client without any additional controller or JavaScript code.
Where to Use Turbo Frames and Turbo Streams?
-
Inline editing without a full page reload
-
Live comment sections or activity feeds
-
Real-time notifications and alerts
-
Search results that update as the user types
-
Shopping carts, like buttons, or any element that updates on interaction
-
Multi-panel dashboards with independently refreshing sections
In Summary
Turbo Frames and Turbo Streams are the core tools in Hotwire for building fast, interactive Rails applications without writing custom JavaScript. Turbo Frames handle scoped request-response updates, while Turbo Streams enable targeted DOM updates and real-time broadcasting to connected clients via Action Cable.