You're building a Rails app. Someone on your team says, We should use React for the frontend.

Maybe they're right. Maybe they're wrong.

Let me help you decide.


The Short Answer

Use React when you need complex, state-heavy interactions that feel like a desktop app.

Use Rails with Hotwire for everything else.

Most apps fall into everything else.


The Cost of Adding React

Before you add React, understand what you're signing up for.

Two Codebases

You now have a Rails API and a React frontend. They live separately. They deploy separately. They have separate dependencies, separate tests, separate build pipelines.

API Contracts

Every time you change how data is structured, you must update both sides. Add a field to a response? Update the React type definition. Change an endpoint? Update both.

This coordination slows you down. It introduces bugs when you forget to update one side.

Authentication Complexity

Session cookies don't work the same way across origins. You'll likely switch to JWT tokens. Now you manage token refresh, storage, and security.

More Moving Parts

  • Webpack or Vite configuration
  • CORS setup
  • Environment variables for API URLs
  • Different deployment workflows

Each moving part can break. Each one adds debugging time.

Slower Onboarding

New developers must learn Rails and React. They must understand how the two communicate. They must debug issues that span both.


When React Makes Sense

React is not always the wrong choice. Here's when it shines.

1. Complex, Interactive UI

Think Google Docs, Figma, or a drag-and-drop dashboard. You have many UI elements that update independently based on user actions.

Rails with Hotwire can handle simple interactions. It struggles with highly dynamic interfaces where dozens of components react to state changes.

2. Real-Time Collaboration

If multiple users edit the same data simultaneously, you need sophisticated client-side state management. React (with something like Yjs or Liveblocks) handles this well.

3. Offline-First Applications

If your app must work without an internet connection and sync later, you need a client-side data store. React Native or PWA with IndexedDB is the right tool.

4. Your Team Already Knows React

If your team has deep React expertise and no Rails frontend experience, the math changes. Developer productivity matters more than architectural purity.

5. You're Building a Mobile App First

React Native shares patterns with React. Using React on the web means you reuse components, hooks, and state management across web and mobile.


The Sweet Spot: Gradual Integration

You don't have to go all in. React can live inside your Rails app.

Option 1: React Components in Rails Views

Use the react-rails gem to sprinkle React components where you need them:

# Gemfile
gem "react-rails"
rails generate react:install
<%# app/views/projects/show.html.erb %>
<%= react_component("TaskList", { tasks: @tasks }) %>

The rest of the page is ERB. Only the complex part is React.

Option 2: Separate Frontend for One Section

Mount a React app on a single route:

# config/routes.rb
Rails.application.routes.draw do
  root "pages#home"

  resources :projects

  # Complex reporting dashboard
  get "/dashboard", to: "dashboard#index"
end
<%# app/views/dashboard/index.html.erb %>
<div id="dashboard-root"></div>
<%= javascript_pack_tag "dashboard" %>

Everything else stays in Rails.

Option 3: Rails API with React Frontend

When you need full separation, keep the Rails API simple:

# app/controllers/api/v1/tasks_controller.rb
class Api::V1::TasksController < ApplicationController
  def index
    tasks = Current.user.tasks
    render json: tasks
  end
end

Use jbuilder or jsonapi-serializer for consistent responses.


The Rails Alternative: Hotwire

Before committing to React, try Hotwire. It handles many dynamic use cases with far less complexity.

Turbo Frames

<%= turbo_frame_tag "task_#{task.id}" do %>
  <%= task.name %>
  <%= link_to "Edit", edit_task_path(task) %>
<% end %>

Turbo Streams

<%= turbo_stream.append "notifications" do %>
  <div class="notification">
    New task assigned to you
  </div>
<% end %>

Stimulus

// app/javascript/controllers/clipboard_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  copy() {
    navigator.clipboard.writeText(this.element.dataset.text)
  }
}
<button data-controller="clipboard" data-clipboard-text="Hello" data-action="click->clipboard#copy">
  Copy
</button>

Most interactive features can be built with these tools. No separate frontend required.


Decision Framework

Ask these questions before choosing React.

Question 1: Do you need offline support?

  • Yes: Consider React with PWA
  • No: Continue

Question 2: Do you need real-time collaboration?

  • Yes: React might be appropriate
  • No: Continue

Question 3: Do you have complex, state-heavy UI?

  • Yes: Evaluate if Hotwire can handle it
  • No: Stick with Rails

Question 4: Does your team already know React?

  • Yes: Consider gradual integration
  • No: Stick with Rails

Question 5: Are you building a mobile app?

  • Yes: React might make sense
  • No: Stick with Rails

If you answered No to most questions, you don't need React.


Real-World Example

A founder came to me with a dashboard app. Users could filter data, apply calculations, and export results.

He assumed he needed React. We built the prototype with Hotwire instead.

  • Lines of code: 400 vs 2,000
  • Development time: 5 days vs 3 weeks
  • Deployment complexity: Simple vs two codebases
  • Onboarding time: 1 day vs 1 week

The Hotwire version worked. Users loved it. He never added React.


Summary

Use Rails + Hotwire Consider React
Most B2B SaaS apps Real-time collaboration
CRUD with simple interactions Offline-first apps
Internal tools Desktop-like complex UI
Marketing sites + blog Mobile app with React Native
Solo founders or small teams Team already knows React

Getting Started with Hotwire

rails new myapp --javascript=importmap

Hotwire is the default. You're already set up.

Read the Hotwire documentation and build a small feature. You might be surprised how much you can do.


*Next post: Architecting Rails for Scale: From MVP to Millions (coming soon)