Hotwire Decoded: When to use Frames vs. Streams

The Hotwire Confusion

If you are new to Rails 7 or 8, you’ve likely stared at the documentation asking: “Both of these update the DOM without a page reload… so which one do I use?”

It is the most common point of confusion.

  • Turbo Frames allow you to decompose a page into independent contexts.
  • Turbo Streams allow you to deliver page changes over WebSocket (or HTTP) to multiple places at once.

Here is the visual guide to making the right choice.

🖼️ Turbo Frames: “The Room”

Visual Mental Model: Imagine your webpage is a house. A Turbo Frame is a specific room with the door closed.

  • If you change the furniture in the Kitchen Frame, the Bedroom Frame doesn’t care.
  • If you click a link inside the Kitchen, the response replaces the Kitchen only.

Rule: “What happens inside the frame, stays inside the frame.”

Use Case: Inline Editing

The classic example. You have a list of messages. You want to edit one without reloading the list.

The View (_message.html.erb):

 id="message_<%= message.id %>">
  

<%= message.content %>

<%= link_to "Edit", edit_message_path(message) %>

The Controller:

def edit
  @message = Message.find(params[:id])
  # Rails renders 'edit.html.erb' automatically.
  # Because the request came from inside a Frame, 
  # Turbo extracts the matching Frame from the response and swaps it.
end

The Result:
The show version of the message is replaced by the edit form version of the message. The rest of the page (header, footer, sidebar) never moves.

When to use Frames:

  • ✅ Lazy Loading (e.g., loading a heavy chart after the page loads).
  • ✅ Tabbed content switching.
  • ✅ Inline editing / Simple CRUD.
  • ✅ Modals.

🌊 Turbo Streams: “The Puppet Master”

Visual Mental Model: Imagine a Puppet Master pulling strings.

  • One action (the user clicks “Send”) triggers multiple changes across the stage.
  • The generic form resets + The new message appears at the bottom + The “Total Messages” counter updates in the header.

Rule: “One action, multiple targets.”

Use Case: Live Chat / Real-time Feeds

You submit a new message. You can’t use a Frame here because the input form is at the bottom of the page, but the new message needs to appear in the list above it. The frame rules would break.

The Controller:

def create
  @message = Message.create(msg_params)

  respond_to do |format|
    format.turbo_stream
    format.html { redirect_to messages_path }
  end
end

The View (create.turbo_stream.erb):


<%= turbo_stream.append "messages_list", partial: "messages/message", locals: { message: @message } %>


<%= turbo_stream.replace "new_message_form", partial: "messages/form", locals: { message: Message.new } %>


<%= turbo_stream.update "msg_counter", plain: Message.count %>

When to use Streams:

  • ✅ Appending/Prepending items to a list.
  • ✅ Updating multiple distinct parts of the page at once.
  • ✅ Real-time broadcasts (ActionCable) where the server pushes updates to other users.
  • ✅ Removing an element (fade out).

The Cheat Sheet (Visual Decision Matrix)

Scenario A: Search Filter

You type in a search box, and the list below updates.
👉 Use a Frame. wrap the input and the list in one Frame. The search acts as a navigation event within the frame.

Scenario B: Shopping Cart

You click “Add to Cart” on a product card. The button changes to “Added!”, AND the little Cart Icon in the navbar updates its number.
👉 Use a Stream. You are touching two completely different areas of the DOM (The product card and the Navbar).

Scenario C: Infinite Scroll

You scroll to the bottom, and more items appear.
👉 Use a Frame. Specifically, a lazy-loading frame with loading="lazy" pointing to the next page of pagination.

Summary

Think of Frames as Scoping. You are narrowing the scope of interaction to a specific HTML element (

).

Think of Streams as Instructions. You are sending a command list (append, remove, update) to the browser to execute wherever it pleases.

Start with Frames. If you hit a wall where you need to affect something outside the box, graduate to Streams.

Which one do you find yourself using more often? Let me know below!

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
multi-modal-inspection-for-industrial-quality-control:-combining-technologies-for-better-defect-detection

Multi-Modal Inspection for Industrial Quality Control: Combining Technologies for Better Defect Detection

Next Post

Lighting Design for Machine Vision, Part 2

Related Posts
harmonyos-next中密码类数据保护场景解析

HarmonyOS Next中密码类数据保护场景解析

本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前 API12)在开发多语言电商平台方面的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。 在当今数字化时代,密码类数据的保护对于应用的安全性和用户体验至关重要。无论是登录账号、进行金融交易还是访问敏感信息,密码都起着关键的作用。HarmonyOS Next作为一款先进的操作系统,其提供的Asset Store Kit为密码类数据的安全存储和管理提供了强大的解决方案。 (一)引言 密码类数据保护的重要性    – 在移动应用领域,密码类数据是用户身份验证的核心凭证。一旦密码泄露,用户的账号安全将受到严重威胁,可能导致个人信息被窃取、财产遭受损失等严重后果。例如,在金融类应用中,如果用户的登录密码被泄露,黑客可能会非法访问用户的账户,进行转账、消费等操作。因此,确保密码类数据的安全性是应用开发者必须首要考虑的问题。 Asset Store Kit的关键作用    – HarmonyOS…
Read More