<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged hotwire</title>
<link>https://coderlegion.com/tag/hotwire</link>
<description>Powered by Question2Answer</description>
<item>
<title>Hotwire vs. React: A Guide for the &quot;One-Person Framework&quot;</title>
<link>https://coderlegion.com/13050/hotwire-vs-react-a-guide-for-the-one-person-framework</link>
<description>&lt;h3 id=&quot;the-default-choice&quot;&gt;The Default Choice&lt;/h3&gt;
&lt;p&gt;For the last five years, the &quot;Standard Web Stack&quot; has been undeniable:&lt;br&gt;
&lt;strong&gt;Backend API (Rails/Node) + SPA Frontend (React/Vue).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is the architecture taught in bootcamps. It is the architecture demanded by recruiters. And for a long time, if you wanted a &quot;modern&quot; feeling application—no page reloads, snappy transitions, real-time updates—it was the only way.&lt;/p&gt;
&lt;p&gt;But it comes with a cost. I call it &lt;strong&gt;The React Tax.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With the maturity of Rails 7 (and now Rails 8) and &lt;strong&gt;Hotwire&lt;/strong&gt;, that tax is no longer mandatory. Here is why I believe Hotwire is the superior choice for 95% of Rails projects.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-two-apps-one-product&quot;&gt;The Problem: Two Apps, One Product&lt;/h3&gt;
&lt;p&gt;When you choose React, you aren't building &quot;an app.&quot; You are building &lt;strong&gt;two apps.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The Backend:&lt;/strong&gt; Dealing with serialization, JWTs, CORS, and versioning.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Frontend:&lt;/strong&gt; Dealing with route management, global state (Redux/Context), effect hooks, and package.json hell.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Suddenly, a simple feature like &quot;Rename a Project&quot; requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frontend: Update UI state optimistically.&lt;/li&gt;
&lt;li&gt;Frontend: Dispatch API call.&lt;/li&gt;
&lt;li&gt;Backend: Handle auth.&lt;/li&gt;
&lt;li&gt;Backend: Update DB.&lt;/li&gt;
&lt;li&gt;Backend: Serialize JSON response.&lt;/li&gt;
&lt;li&gt;Frontend: Handle success/error.&lt;/li&gt;
&lt;li&gt;Frontend: Re-sync local state.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;With Hotwire, the flow is:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Controller: Update DB.&lt;/li&gt;
&lt;li&gt;View: Render HTML.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;1-the-single-source-of-truth-myth&quot;&gt;1. The &quot;Single Source of Truth&quot; Myth&lt;/h3&gt;
&lt;p&gt;The hardest problem in Computer Science is naming things. The second hardest is &lt;strong&gt;Cache Invalidation.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you duplicate your database state into a Redux store or React Query cache, you are inviting bugs. &lt;em&gt;Is the user list stale? Did the socket update the count? Why does the UI say &quot;Premium&quot; but the API returned 403?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hotwire rejects this premise.&lt;br&gt;
With &lt;strong&gt;Turbo&lt;/strong&gt;, the server is the single source of truth. When data changes, you don't update a client-side JSON cache; you simply replace the HTML chunk on the screen with fresh HTML from the server.&lt;/p&gt;
&lt;p&gt;You eliminate an entire class of &quot;State desync&quot; bugs because &lt;strong&gt;you have no client-side state.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;2-velocity-the-one-person-framework-&quot;&gt;2. Velocity: The &quot;One Person Framework&quot;&lt;/h3&gt;
&lt;p&gt;Rails 8 is pushing the concept of the &quot;One Person Framework.&quot; The idea is that a single developer should be able to build a startup that used to require a team of 5.&lt;/p&gt;
&lt;p&gt;If you are a solo dev or a small team using React, you are spending 50% of your time managing the &lt;strong&gt;glue&lt;/strong&gt; between your backend and frontend.&lt;/p&gt;
&lt;p&gt;With Hotwire (Turbo Drive + Turbo Frames + Stimulus), you stay in Ruby/ERB land for 90% of the work. You write standard Rails views. You get SPA-speed navigation for free via Turbo Drive. You get dynamic partial updates via Frames.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Context Switch Cost:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;React:&lt;/strong&gt; Switch from Ruby to JS. Switch from ERB to JSX. Switch from RSpec to Jest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hotwire:&lt;/strong&gt; Stay in the flow.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-but-react-feels-better-&quot;&gt;3. &quot;But React feels better&quot;&lt;/h3&gt;
&lt;p&gt;This was true in 2016. It is not true today.&lt;/p&gt;
&lt;p&gt;Turbo Drive (which intercepts link clicks and form submissions) makes a standard Rails app feel instant. It merges the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; and replaces the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; without a full browser reload.&lt;/p&gt;
&lt;p&gt;Need real-time? &lt;strong&gt;Turbo Streams&lt;/strong&gt; over ActionCable allows you to broadcast updates to millions of users with a few lines of Ruby.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;# app/models/message.rb
after_create_commit { broadcast_append_to &quot;chat_room&quot; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That one line creates a WebSocket connection that appends the new message to the DOM of every active user. Doing this in React requires setting up a socket context, listeners, state reducers, and safety checks.&lt;/p&gt;
&lt;h3 id=&quot;when-should-you-use-react-&quot;&gt;When SHOULD you use React?&lt;/h3&gt;
&lt;p&gt;I am not a React hater. It is an incredible piece of engineering. You &lt;em&gt;should&lt;/em&gt; use React (or Vue/Svelte) if:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;You are building a high-fidelity tool:&lt;/strong&gt; e.g., Figma, an in-browser video editor, or a complex drag-and-drop Trello clone.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You need &quot;Offline First&quot;:&lt;/strong&gt; If the app must function 100% without an internet connection (PWA with heavy local sync).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your API serves multiple clients:&lt;/strong&gt; If you have a Mobile App, a Web App, and a Desktop App that all need the exact same API, maybe a decoupled frontend makes sense (though native apps are moving to Server-Driven UI too!).&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;the-verdict&quot;&gt;The Verdict&lt;/h3&gt;
&lt;p&gt;For the vast majority of SaaS products—dashboards, marketplaces, social networks, project management tools—the &quot;React Tax&quot; is a waste of resources.&lt;/p&gt;
&lt;p&gt;Hotwire gives you 80% of React's interactivity with 10% of the complexity.&lt;/p&gt;
&lt;p&gt;If you want to ship features, use Hotwire. If you want to configure Webpack, use React.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Are you sticking with the React ecosystem, or have you tried the Hotwire life? Let’s discuss below.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13050/hotwire-vs-react-a-guide-for-the-one-person-framework</guid>
<pubDate>Tue, 17 Mar 2026 12:47:49 +0000</pubDate>
</item>
</channel>
</rss>