|
| 1 | +# Example Migrations |
| 2 | + |
| 3 | +Teams evaluating React on Rails are usually not starting from a blank Rails app. |
| 4 | + |
| 5 | +They already have one of these: |
| 6 | + |
| 7 | +- `react-rails` |
| 8 | +- `vite_rails` |
| 9 | +- a custom Rails-side React helper |
| 10 | + |
| 11 | +Some teams also arrive from Inertia-first apps. We treat those as a separate |
| 12 | +architecture case study because they are usually broader page-shell migrations, |
| 13 | +not narrow React mount migrations. If that is your starting point, begin with |
| 14 | +[Compare with alternatives](../getting-started/comparing-react-on-rails-to-alternatives.md). |
| 15 | + |
| 16 | +This page tracks practical migration references for those cases. |
| 17 | + |
| 18 | +## What makes a useful migration example |
| 19 | + |
| 20 | +The best examples are: |
| 21 | + |
| 22 | +1. Real Rails applications, not toy demos |
| 23 | +2. Small PRs that convert one page, mount point, or component boundary |
| 24 | +3. Honest about blockers such as old lockfiles, native gems, or custom frontend bridges |
| 25 | +4. Measured with before-and-after performance or maintainability notes instead of marketing claims |
| 26 | + |
| 27 | +## Current public references |
| 28 | + |
| 29 | +### Published example repos |
| 30 | + |
| 31 | +These maintainer-owned references are the stable starting set. Add community |
| 32 | +examples here after they have landed or stabilized enough to inspect. |
| 33 | + |
| 34 | +1. [react-rails example app: `react-rails-to-react-on-rails` snapshot](https://github.com/shakacode/react-rails-example-app/tree/c6b794a4b96746dbbc98a46f31119171109d70b0) — |
| 35 | + covers an older `react-rails` v3 → `react_on_rails` v13.4 migration, so treat |
| 36 | + it as a structural reference and follow current migration guides for gem and |
| 37 | + configuration specifics |
| 38 | +2. [react-on-rails-migration-example](https://github.com/shakacode/react-on-rails-migration-example) — |
| 39 | + demonstrates a Rails 7-era `react-rails` → `react_on_rails` migration with |
| 40 | + Shakapacker client/server bundles and SSR setup, based on |
| 41 | + [ganchdev/react-rails-example](https://github.com/ganchdev/react-rails-example) |
| 42 | + |
| 43 | +### In-progress migration work |
| 44 | + |
| 45 | +In-progress third-party migration PRs are tracked in the |
| 46 | +[example-migrations meta issue](https://github.com/shakacode/react_on_rails/issues/3125) |
| 47 | +instead of this docs page. |
| 48 | + |
| 49 | +That keeps the public docs focused on durable references while the meta issue can |
| 50 | +carry working notes about draft PRs, maintainer coordination, blockers, and proof |
| 51 | +artifacts that may change quickly. |
| 52 | + |
| 53 | +When a public migration becomes a stable reference, add it to the published example |
| 54 | +list above with a short proof note. |
| 55 | + |
| 56 | +## Example categories |
| 57 | + |
| 58 | +### `react-rails` to React on Rails |
| 59 | + |
| 60 | +This is usually the cleanest migration path: primarily a gem swap and mount |
| 61 | +registration change while the app architecture stays intact during |
| 62 | +slice-by-slice conversion. |
| 63 | + |
| 64 | +### `vite_rails` to React on Rails |
| 65 | + |
| 66 | +This is more of an asset and entrypoint migration than a component rewrite: the |
| 67 | +route behavior should stay stable while registration moves into the React on |
| 68 | +Rails and Shakapacker flow. |
| 69 | + |
| 70 | +### Custom Rails React bridge to React on Rails |
| 71 | + |
| 72 | +This is common in mature apps that built a thin wrapper around React mounts. |
| 73 | + |
| 74 | +Treat the wrapper as the migration boundary: preserve the Rails-side props |
| 75 | +contract, replace one helper-backed component first, and remove the wrapper |
| 76 | +later. |
| 77 | + |
| 78 | +No dedicated guide exists yet. If your app uses this pattern and you want to |
| 79 | +contribute an example, see [Contribute an example](#contribute-an-example). |
| 80 | +The [react-rails migration guide](./migrating-from-react-rails.md) covers the |
| 81 | +nearest-neighbor mechanics for helper syntax and component registration. |
| 82 | + |
| 83 | +## What counts as proof |
| 84 | + |
| 85 | +Not every good migration example is performance-first. |
| 86 | + |
| 87 | +When the change is performance-first, compare the same route on the baseline branch and the migration branch. At minimum, record: |
| 88 | + |
| 89 | +1. Response timing |
| 90 | +2. HTML size |
| 91 | +3. Route JavaScript bytes |
| 92 | +4. Number of JS assets needed for the route |
| 93 | +5. Hydration warnings or client boot errors |
| 94 | + |
| 95 | +If possible, also record browser load metrics such as FCP, LCP, CLS, and TBT, |
| 96 | +plus interaction metrics such as INP. TBT is captured by Lighthouse; INP |
| 97 | +requires field data or a real-user monitoring tool. |
| 98 | + |
| 99 | +When the change is maintainability-first, record: |
| 100 | + |
| 101 | +1. The custom bridge, oversized mount, or repo-specific contract that existed before the migration |
| 102 | +2. The standardized React on Rails helper or smaller boundary that replaced it |
| 103 | +3. What got easier to review, test, or evolve afterward |
| 104 | +4. The validation that supports the claim |
| 105 | + |
| 106 | +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. |
| 107 | + |
| 108 | +## Contribute an example |
| 109 | + |
| 110 | +If your migration could help other teams evaluate React on Rails, [open an issue](https://github.com/shakacode/react_on_rails/issues/new/choose) or [submit a PR](https://github.com/shakacode/react_on_rails/compare) adding it to this page, and include: |
| 111 | + |
| 112 | +1. The integration you started from, such as `react-rails`, `vite_rails`, or a custom helper |
| 113 | +2. The first slice you picked and why it was small enough to review |
| 114 | +3. The proof you captured, whether that was performance, maintainability, or both |
| 115 | +4. The validation you ran locally or in CI |
| 116 | + |
| 117 | +The most useful next examples are: |
| 118 | + |
| 119 | +1. `react-rails` apps that migrate one Rails-owned mount at a time |
| 120 | +2. Modern `vite_rails` apps where one Rails-owned island can move before a broader asset rewrite |
| 121 | +3. Apps with a custom Rails-side React bridge where one helper-backed boundary can be replaced before removing the wrapper |
| 122 | +4. Upgrades from older `react_on_rails` versions to current maintained defaults |
| 123 | + |
| 124 | +## How to use these examples |
| 125 | + |
| 126 | +Use this page together with the specific migration guide that matches your current stack: |
| 127 | + |
| 128 | +1. [Migrate from `react-rails`](./migrating-from-react-rails.md) |
| 129 | +2. [Migrate from `vite_rails`](./migrating-from-vite-rails.md) |
| 130 | + |
| 131 | +Other migration paths: |
| 132 | + |
| 133 | +1. [Webpack to Rspack](./migrating-from-webpack-to-rspack.md) |
| 134 | +2. [Babel to SWC](./babel-to-swc-migration.md) |
| 135 | + |
| 136 | +The Rails 5 API-only and AngularJS paths also live in the **Migration Guides** sidebar. For React Server Components migration content, start with [Migrating to RSC](./migrating-to-rsc.md). |
| 137 | + |
| 138 | +The migration guides explain the mechanics. This page shows what those mechanics look like in real repos. |
0 commit comments