Hotwire vs. React: A Guide for the 'One-Person Framework'
Source: Dev.to
The Default Choice
For the last five years, the “Standard Web Stack” has been undeniable:
Backend API (Rails/Node) + SPA Frontend (React/Vue).
It is the architecture taught in bootcamps, demanded by recruiters, and, for a long time, the only way to get a “modern” feeling application—no page reloads, snappy transitions, real‑time updates.
But it comes with a cost. I call it the React Tax.
With the maturity of Rails 7 (and now Rails 8) and Hotwire, that tax is no longer mandatory. Here is why I believe Hotwire is the superior choice for 95 % of Rails projects.
The hidden cost of React
When you choose React, you aren’t building a single app; you’re building two:
- Backend – serialization, JWTs, CORS, versioning.
- Frontend – route management, global state (Redux/Context), effect hooks,
package.jsonhell.
A simple feature like “Rename a Project” expands into many steps:
- Frontend: update UI state optimistically.
- Frontend: dispatch API call.
- Backend: handle auth.
- Backend: update DB.
- Backend: serialize JSON response.
- Frontend: handle success/error.
- Frontend: re‑sync local state.
Hotwire’s streamlined flow
With Hotwire the flow collapses to:
- Controller – update DB.
- View – render HTML.
The hardest problem in computer science is naming things. The second hardest is cache invalidation. Duplicating database state into a Redux store or React Query cache invites bugs: stale lists, mismatched counts, UI showing “Premium” while the API returns 403. Hotwire rejects this premise.
Turbo makes the server the single source of truth. When data changes, you replace the HTML chunk on the screen with fresh HTML from the server, eliminating an entire class of “state desync” bugs because there is no client‑side state.
One‑Person Framework
Rails 8 pushes the concept of the “One Person Framework”: a single developer should be able to build a startup that previously required a team of five. If you’re a solo dev or a small team using React, you spend roughly 50 % of your time managing the glue between backend and frontend.
With Hotwire (Turbo Drive + Turbo Frames + Stimulus) you stay in Ruby/ERB land for about 90 % of the work:
- Write standard Rails views.
- Get SPA‑speed navigation for free via Turbo Drive.
- Get dynamic partial updates via Frames.
Context switch cost
| React | Hotwire |
|---|---|
| Switch from Ruby to JS | Stay in the flow |
| Switch from ERB to JSX | — |
| Switch from RSpec to Jest | — |
This was true in 2016; it is not true today.
Turbo Drive and Turbo Streams
Turbo Drive intercepts link clicks and form submissions, making a standard Rails app feel instant. It merges the and replaces the without a full browser reload.
Need real‑time? Turbo Streams over ActionCable lets you broadcast updates to millions of users with a few lines of Ruby:
# app/models/message.rb
after_create_commit { broadcast_append_to "chat_room" }
That single line creates a WebSocket connection that appends the new message to the DOM of every active user. Doing the same in React requires setting up a socket context, listeners, state reducers, and safety checks.
When React still makes sense
I am not a React hater; it is an incredible piece of engineering. You should use React (or Vue/Svelte) if:
- You are building a high‑fidelity tool (e.g., Figma, an in‑browser video editor, a complex drag‑and‑drop Trello clone).
- You need “Offline First” (a PWA that must function 100 % without an internet connection).
- Your API serves multiple clients (mobile, web, desktop) that all need the exact same API—though native apps are moving toward server‑driven UI as well.
The majority case
For the vast majority of SaaS products—dashboards, marketplaces, social networks, project‑management tools—the “React Tax” is a waste of resources. Hotwire gives you roughly 80 % of React’s interactivity with about 10 % of the complexity.
If you want to ship features quickly, use Hotwire.
If you want to configure Webpack, use React.
Are you sticking with the React ecosystem, or have you tried the Hotwire life? Let’s discuss below.