docs/oss/migrating/example-migrations.md
See also: Examples and Migration References for the broader index of public reference repos (starters, in-repo samples, RSC demos, and live demos). This page focuses specifically on migration references.
Teams evaluating React on Rails are usually not starting from a blank Rails app.
They already have one of these:
react-railsvite_railsSome teams also arrive from Inertia-first apps. We treat those as a separate architecture case study because they are usually broader page-shell migrations, not narrow React mount migrations. If that is your starting point, begin with Compare with alternatives.
This page tracks practical migration references for those cases.
The best examples are:
These maintainer-owned references are the stable starting set. Add community examples here after they have landed or stabilized enough to inspect.
react-rails-to-react-on-rails snapshot —
covers an older react-rails v3 → react_on_rails v13.4 migration, so treat
it as a structural reference and follow current migration guides for gem and
configuration specificsreact-rails → react_on_rails migration with
Shakapacker client/server bundles and SSR setup, based on
ganchdev/react-rails-examplereact-rails in a
more realistic codebase, useful when the smaller migration above does not
match the scale of your applicationIn-progress third-party migration PRs are tracked in the example-migrations meta issue instead of this docs page.
That keeps the public docs focused on durable references while the meta issue can carry working notes about draft PRs, maintainer coordination, blockers, and proof artifacts that may change quickly. See the Proof artifact template for the recommended fields to capture.
When a public migration becomes a stable reference, add it to the published example list above with a short proof note.
react-rails to React on RailsThis is usually the cleanest migration path: primarily a gem swap and mount registration change while the app architecture stays intact during slice-by-slice conversion.
vite_rails to React on RailsThis is more of an asset and entrypoint migration than a component rewrite: the route behavior should stay stable while registration moves into the React on Rails and Shakapacker flow.
This is common in mature apps that built a thin wrapper around React mounts.
Treat the wrapper as the migration boundary: preserve the Rails-side props contract, replace one helper-backed component first, and remove the wrapper later.
No dedicated guide exists yet. If your app uses this pattern and you want to contribute an example, see Contribute an example. The react-rails migration guide covers the nearest-neighbor mechanics for helper syntax and component registration.
Not every good migration example is performance-first.
When the change is performance-first, compare the same route on the baseline branch and the migration branch. At minimum, record:
If possible, also record browser load metrics such as FCP, LCP, CLS, and TBT, plus interaction metrics such as INP. TBT is captured by Lighthouse; INP requires field data or a real-user monitoring tool.
When the change is maintainability-first, record:
Use maintainability notes when that is the honest win. Do not force a weak benchmark onto an example whose real value is simpler ownership or a narrower integration boundary.
Use this template in the migration PR description, linked issue, or a short docs/ note in the example repository. Fill in the fields that match the claim, mark evidence fields that were not measured as "not claimed", and mark "Known blockers or caveats" as "none" when checked and absent.
| Field | What to record |
|---|---|
| Baseline ref | Commit SHA, branch, or tag before the migration |
| Migration ref | Commit SHA, branch, this PR if it is the migration PR, or another PR after the migration |
| Route or component | The exact Rails route, controller action, or React mount point |
| Date captured | YYYY-MM-DD or release milestone when the evidence was collected |
| React on Rails version | Target gem/npm package version, or a branch/PR link if targeting a pre-release |
| Starting integration | react-rails, vite_rails, custom helper, older react_on_rails version, or other |
| Migration slice | What changed and what intentionally stayed out of scope |
| Performance evidence | Response timing, HTML size, JS bytes, asset count, Lighthouse/WebPageTest/RUM metrics, or "not claimed"; see What counts as proof |
| Maintainability evidence | Removed custom bridge code, smaller mount boundary, standardized helper usage, or "not claimed"; see What counts as proof |
| Validation | Test commands, build commands, browser smoke checks, screenshots, or CI links; required |
| Known blockers or caveats | Native services, old lockfiles, auth setup, browser-only flows, environment assumptions, or "none" |
| Honest summary sentence | One sentence contributors can write and maintainers can quote without overstating the result |
Copy this table when opening a migration PR:
<!-- Use "not claimed" for evidence fields that do not apply. Use "none" for Known blockers when there are none. -->
<!-- Validation is required; do not leave it blank. -->
| Field | Value |
| ------------------------- | ----------------- |
| Baseline ref | |
| Migration ref | |
| Route or component | |
| Date captured | |
| React on Rails version | |
| Starting integration | |
| Migration slice | |
| Performance evidence | |
| Maintainability evidence | |
| Validation | <!-- required --> |
| Known blockers or caveats | |
| Honest summary sentence | |
Example summary sentences:
If your migration could help other teams evaluate React on Rails, open an issue or submit a PR adding it to this page, and include:
react-rails, vite_rails, or a custom helperThe most useful next examples are:
react-rails apps that migrate one Rails-owned mount at a timevite_rails apps where one Rails-owned island can move before a broader asset rewritereact_on_rails versions to current maintained defaultsUse this page together with the specific migration guide that matches your current stack:
Other migration paths live in the Migration Guides sidebar:
React Server Components migration content lives under React on Rails Pro in the sidebar:
The migration guides explain the mechanics. This page shows what those mechanics look like in real repos.