# react-rails: Server-Rendered React Inside Rails Views

> react-rails wires React components into Rails views, controllers and the asset pipeline, with server-side rendering built in. It fits teams that want React on an existing Rails app without running a separate frontend build, and the README itself points elsewhere for new work.

**reactjs/react-rails** — Integrate React.js with Rails views and controllers, the asset pipeline, or webpacker.

- Repository: https://github.com/reactjs/react-rails
- Stars: 6,774 · Forks: 739
- Language: JavaScript
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/reactjs-react-rails

## What react-rails does that a plain Rails view cannot

A Rails view is server-rendered HTML with no component model. If you want React in that view, you normally need a separate JavaScript entry point, a mounting convention, and some way to pass Rails data into the component. react-rails supplies all three: a view helper that mounts a component by name, a UJS layer that finds those mount points in the page and renders them, and a server-side rendering path that produces the initial HTML before the browser runs any JavaScript.

The README lists the scope plainly: it renders React server-side and client-side, supports Shakapacker v7, Propshaft, and Sprockets 4.x and 3.x, and accepts JSX, ES6, TypeScript and CoffeeScript. That combination is the point. The gem is not a JavaScript framework wrapper; it is a bridge between Rails' rendering pipeline and React's component model, and it works whether your assets come from Sprockets or from a webpack-based pipeline.

The audience is specific: teams with an existing Rails application, ERB or Haml views, and a desire to add interactive components without rewriting the front end. It is a poor fit for a greenfield React application that happens to have a Rails API behind it, because in that case the Rails view layer is not where the UI lives.

## How the mount point, the UJS layer and the renderer fit together

The mechanism has three parts. First, a Rails view calls a helper to place a component on the page. Second, the react_ujs package, published as react_ujs on npm, scans the document for those mount points and instantiates the matching component on the client. Third, for server-side rendering, the gem renders the component to a string on the server and the view emits that HTML, so the first paint contains real markup rather than an empty container.

The npm package is the client half. Its package.json declares react and react-dom as dependencies at ^18.2.0, and the build script runs webpack inside the react_ujs directory. The repository keeps the JavaScript in a react_ujs/ folder and the Ruby side in lib/, with the gem packaged through react-rails.gemspec.

Component naming is the contract that ties the two halves together. The documentation covers component name resolution and file naming under the Shakapacker path, and the UJS docs describe mounting and unmounting plus a getConstructor hook for resolving a component from its name. That indirection is what lets a Rails helper refer to a component by a string rather than importing it directly, and it is also the part that tends to confuse people when a component renders on the server but not in the browser.

Server-side rendering has its own configuration surface, and the documentation separates configuration, JavaScript state and a custom server renderer. The existence of a custom renderer option matters: the default path executes JavaScript in the Ruby process, and a custom renderer is the escape hatch when that execution model does not fit.

## Installing react-rails and rendering a first component

The README points to docs/get-started.md for setup and splits the instructions by asset pipeline: one path for Shakapacker and one for the asset pipeline. The README does not print a Gemfile line or an install command, so the starting point is that document rather than a snippet here. What the repository does show is the packaging: the gem is built from react-rails.gemspec, and the JavaScript half is the react_ujs package whose package.json declares react and react-dom at ^18.2.0 with a build script that runs webpack inside the react_ujs directory.

Once the gem is in place, the component generator documented in docs/component-generator.md creates a component file and its template. That document also covers using the generator with JBuilder, camelizing props, and changing the component templates. Views then mount the component through the view helper in docs/view-helper.md, which also explains how to write a custom view helper when the default one does not match your conventions.

If your assets come from Shakapacker rather than Sprockets, follow the Shakapacker section of docs/get-started.md instead; it covers component name resolution, file naming, TypeScript support and a test component. Do not mix the two paths. The README presents them as alternatives, and the asset pipeline path includes its own notes on custom JSX transformers, transform plugin options and React versions.

## The maintenance picture, stated plainly

The most recent release listed is v2.6.2 from 2022-04-06, while the repository's last push was on 2026-07-31. That gap between the last tagged release and the last commit is the first thing to check against your own risk tolerance. The README is titled React-Rails v3 and describes a 2.7-stable branch for older documentation, and the npm package react_ujs is at version 3.3.1, so the v3 line exists in the repository even though the release list stops at 2.6.2.

More directly: the README itself recommends considering a migration. It states that while ShakaCode will continue to support the gem, readers might consider migrating to React on Rails or React on Rails Pro with proper Node rendering, and it gives two reasons. React on Rails receives much more active development and testing, and the ReactRailsUJS implementation is compared unfavorably to the ReactOnRails Node package, which is written in TypeScript. The README also notes that React on Rails has work underway for React Server Components.

That is an unusual thing for a project's own README to say, and it should shape how you read everything else. The gem is not abandoned, but its own documentation positions it behind a sibling project. If you are choosing today, treat react-rails as a supported integration for existing applications rather than the direction the maintainers are investing in.

## Where react-rails is the wrong tool

The clearest failure mode is a new application. If nothing is built yet, the README's own recommendation points to React on Rails, and the migration document exists precisely because teams make that move. Starting on react-rails and migrating later costs more than starting on the recommended path.

Server-side rendering is the second constraint. The gem renders on the server through a JavaScript execution path in Ruby, and the documentation offers a custom server renderer for cases the default does not cover. That is a real limit: if your components depend on browser-only APIs, or if you need the rendering to happen in a Node process, the default server renderer is not the right shape. React on Rails Pro is described in the README as offering proper Node rendering, which is a direct acknowledgment of this boundary.

React Server Components are a third. The README says that work on React Server Components is underway in React on Rails, and lists no equivalent for react-rails. If your roadmap depends on that React feature, this gem is not the vehicle.

The fourth case is subtler. The gem's value comes from living inside Rails' view and asset pipeline. If your team has already moved to a standalone frontend build with its own routing and deployment, the Rails view helper adds a layer you do not need. At that point the Rails app is an API, and react-rails is answering a question you stopped asking.

## React on Rails, Vite and the API-only split

The README names React on Rails as the migration target, and the difference is not cosmetic. React on Rails is a separate gem with its own Node package written in TypeScript, and the README describes it as receiving much more active development and testing. Its documented roadmap includes React Server Components, and React on Rails Pro is described as providing proper Node rendering. So the split is: react-rails renders through the Rails asset pipeline with a Ruby-side JavaScript execution path, while React on Rails moves more of the rendering and packaging into Node tooling.

The migration document in the repository, docs/migrating-from-react-rails-to-react_on_rails.md, lays out why and how, and even includes an LLM-assisted migration prompt for teams that want a faster start. That document is the honest comparison, because it is written by the people who maintain both projects.

A second alternative is not to use either gem. A Rails API with a separate frontend application is a common shape, and it sidesteps the component-name resolution and the asset pipeline entirely. The cost is a second deployment and a second set of build tooling, which is exactly what react-rails exists to avoid. The choice is between integration complexity inside Rails and operational complexity outside it.

Vite is a third path that appears in search interest around this project, but the README does not document a Vite integration. Its supported asset paths are Shakapacker, Propshaft and Sprockets. Treat any Vite setup as something you would assemble yourself, not something the gem provides.

## Licence and upgrade cost

The gem is licensed under Apache-2.0, and the repository carries a LICENSE file at the top level alongside a SECURITY.md and a CODE_OF_CONDUCT.md. Apache-2.0 includes an express patent grant and requires that you preserve notices and state significant changes when redistributing. That is the shape of the obligation, not legal advice; check it against how you ship the code.

The upgrade surface is documented rather than left to discovery. docs/upgrading.md covers the 2.7 to 3.0 path and an older 2.3 to 2.4 path, and the README points to the 2.7-stable branch for version 2.7 documentation. docs/common-errors.md collects known problems, including a warning about resolving react-dom/client on React versions below 18, an undefined Set error, TheRubyRacer, HMR, and tests placed inside the component directory. Those entries are the practical upgrade checklist.

The VERSIONS.md file at the repository root and the react-builds/ directory are where version compatibility is tracked. Because the JavaScript package pins react and react-dom at ^18.2.0, a React major upgrade is a coordinated change across the gem, the npm package and your application, not a dependency bump you can do in isolation.

## Conclusion

Adopt react-rails if you have a Rails app already serving views through Sprockets, Propshaft or Shakapacker and you want React components rendered from ERB with optional server-side rendering, without standing up a separate Node service. Do not adopt it for a new React-first application, for React Server Components, or if you need the JavaScript bundle to be the primary deliverable. Before committing, verify your Rails and Sprockets versions against the compatibility list in the README, confirm which React version your app resolves, and read docs/migrating-from-react-rails-to-react_on_rails.md first, because the README recommends that migration for teams that want continued React feature work.

## FAQ

### What are the main differences between React and Rails?

They are not competing tools. Rails is the server framework that renders views and serves the application; React is the component library, and react-rails is the bridge that lets Rails views mount React components and render them server-side and client-side.

### Is React still relevant in 2026?

The README does not discuss React's general relevance. It does state that React on Rails has work underway for React Server Components, and that react-rails pins react and react-dom at ^18.2.0 in the react_ujs package.

### Is Rails frontend or backend?

Rails is the server side, and react-rails is what lets it also own the front end: the README describes rendering React server-side and client-side from Rails views, using Sprockets, Propshaft or Shakapacker for assets.

### Why are people moving away from React?

The README says nothing about people moving away from React. It does say readers might consider migrating from react-rails to React on Rails, and links docs/migrating-from-react-rails-to-react_on_rails.md with the steps.

## Sources

- [Issues](https://github.com/reactjs/react-rails/issues)
- [License: Apache-2.0](https://github.com/reactjs/react-rails/blob/main/LICENSE)
- [reactjs/react-rails on GitHub](https://github.com/reactjs/react-rails)
- [README](https://github.com/reactjs/react-rails/blob/main/README.md)
- [Releases](https://github.com/reactjs/react-rails/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/reactjs-react-rails
