Skip to content

docs: address RSC pitfalls review follow-ups (#3155)#3156

Merged
justin808 merged 3 commits intomainfrom
jg/3155-rsc-docs-followup
Apr 18, 2026
Merged

docs: address RSC pitfalls review follow-ups (#3155)#3156
justin808 merged 3 commits intomainfrom
jg/3155-rsc-docs-followup

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Apr 18, 2026

Summary

Applies the five documentation review comments from PR #3087 that were triaged to issue #3155:

  • docs/oss/building-features/node-renderer/basics.md — Add missing runs-on: ubuntu-latest to the GitHub Actions workflow example so the snippet is copy-paste valid.
  • docs/oss/migrating/rsc-troubleshooting.md — Correct the resolve.fallback: false inline comment to say "omit these modules (no require() call emitted)", matching the paragraph below it (no empty-module shim is generated).
  • docs/pro/react-server-components/upgrading-existing-pro-app.md — Expand the audit checklist to include the React hooks (useRef, useReducer, useCallback, useMemo, useId, useOptimistic), React DOM hooks (useFormStatus), and ReactOnRails.authenticityToken that were listed under "What to look for" but missing from the checklist.
  • docs/oss/migrating/rsc-troubleshooting.md — Reorder the MessageChannel Not Defined section to lead with the recommended additionalContext fix (injecting Node's native MessageChannel from node:worker_threads) and demote BannerPlugin to a labeled fallback, so readers encounter the preferred approach first.
  • docs/pro/react-server-components/upgrading-existing-pro-app.md — Clarify fetch under "Browser APIs": it's a Node.js global since v18 and works in Server Components. The list now only flags fetch calls inside useEffect, which are already captured by the hooks list above.

Fixes #3155

Test plan

  • Prettier check (npx prettier --check) passes on all three modified docs
  • Lefthook hooks (trailing-newlines, markdown-links, prettier) passed on commit
  • No code changes — documentation only

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only updates that adjust examples and recommended fixes; no runtime behavior changes, so risk is low aside from potential reader confusion if guidance is misapplied.

Overview
Updates RSC/Node Renderer docs to make setup and troubleshooting guidance more accurate and copy/paste-ready.

The CI workflow snippet now includes runs-on: ubuntu-latest, the webpack resolve.fallback: false explanation is clarified, and the MessageChannel is not defined section is reordered to recommend injecting Node’s native MessageChannel via additionalContext (with BannerPlugin polyfill as an explicit fallback). The Pro RSC upgrade guide expands the client-API audit checklist to cover additional hooks/APIs and clarifies that fetch is usable in Server Components (flag it only when used in useEffect).

Reviewed by Cursor Bugbot for commit 6ba6295. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Documentation
    • Specified explicit runner environment for Node Renderer test workflow
    • Updated MessageChannel troubleshooting to recommend injecting Node’s MessageChannel at the renderer level, with the webpack polyfill noted as a fallback
    • Clarified that fetch is usable in Server Components and expanded the audit checklist to include additional React hooks and related APIs

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 18, 2026

Walkthrough

Documentation changes: add missing runs-on in a CI example, reorder MessageChannel troubleshooting to recommend injecting Node's native MessageChannel via renderer additionalContext (BannerPlugin polyfill now fallback), and expand/adjust the React Server Components upgrade audit checklist and browser-API guidance (remove fetch as a browser-only API).

Changes

Cohort / File(s) Summary
CI workflow
docs/oss/building-features/node-renderer/basics.md
Added runs-on: ubuntu-latest to the GitHub Actions test job example so the YAML is valid.
MessageChannel troubleshooting
docs/oss/migrating/rsc-troubleshooting.md
Reordered fixes to lead with renderer additionalContext that injects Node's native MessageChannel; moved BannerPlugin polyfill to fallback, clarified polyfill's synchronous behavior and decision criteria, and corrected inline explanatory comment about webpack resolve.fallback.
RSC upgrade audit & browser API guidance
docs/pro/react-server-components/upgrading-existing-pro-app.md
Removed fetch from the "Browser APIs" must-use-'use client' list, expanded the grep/audit checklist to include additional hooks and APIs (useRef, useReducer, useCallback, useMemo, useId, useOptimistic, useFormStatus, ReactOnRails.authenticityToken, etc.).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 I hopped through docs with nimble feet,
Mended CI steps and made guides neat.
Native MessageChannel leads the line,
Hooks assembled, fetch reclined.
A tiny hop toward clearer light — hooray and sweet! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: addressing RSC pitfalls review follow-ups from issue #3155 with documentation fixes.
Linked Issues check ✅ Passed All five objectives from issue #3155 are substantially addressed: runs-on added to workflow [1], inline comment corrected about module omission [2], audit checklist expanded with additional hooks [3], MessageChannel section reordered to lead with additionalContext [4], and fetch guidance clarified for Node globals [5].
Out of Scope Changes check ✅ Passed All changes are directly scoped to the five documentation fixes specified in issue #3155; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jg/3155-rsc-docs-followup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 18, 2026

Greptile Summary

This is a documentation-only PR that applies five follow-up fixes from review issue #3155: adding a missing runs-on: key to a GitHub Actions snippet, correcting a misleading resolve.fallback inline comment, reordering the MessageChannel troubleshooting section to lead with the preferred additionalContext fix, expanding the RSC audit checklist with additional React hooks and ReactOnRails.authenticityToken, and clarifying that bare fetch calls work fine in Server Components since Node.js v18.

Confidence Score: 5/5

Documentation-only PR with no code changes — safe to merge.

All five changes are technically accurate corrections to existing documentation: the YAML snippet fix, inline comment correction, MessageChannel section reordering, expanded hooks checklist, and fetch Node.js v18 clarification are all improvements with no P0 or P1 findings.

No files require special attention.

Important Files Changed

Filename Overview
docs/oss/building-features/node-renderer/basics.md Adds runs-on: ubuntu-latest to a GitHub Actions YAML snippet — minimal, correct fix making the example copy-paste valid.
docs/oss/migrating/rsc-troubleshooting.md Two independent improvements: corrects the resolve.fallback: false inline comment (omit vs. empty-module shim) and reorders the MessageChannel section to present the additionalContext approach first as recommended, with BannerPlugin demoted to a labeled fallback. Both changes are technically accurate.
docs/pro/react-server-components/upgrading-existing-pro-app.md Expands the audit checklist with missing React hooks and ReactOnRails.authenticityToken, and refines the fetch Browser API note to reflect Node.js v18+ global availability. Accurate and consistent with the surrounding "What to look for" guidance.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[MessageChannel Not Defined Error] --> B{Renderer config accessible?}
    B -- Yes --> C["**Recommended**\nadditionalContext approach\nrequire('node:worker_threads').MessageChannel\ninjected into VM sandbox\n→ correct async scheduling"]
    B -- No --> D["**Fallback**\nBannerPlugin polyfill\ninjected at bundle top\n→ synchronous delivery\nmay cause subtle bugs"]
    C --> E[Error resolved]
    D --> F{Unexpected rendering bugs?}
    F -- Yes --> C
    F -- No --> E
Loading

Reviews (1): Last reviewed commit: "docs: address RSC pitfalls review follow..." | Re-trigger Greptile

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

Documentation-only review — accurate changes with a few minor suggestions (see inline comments and details below). No correctness or security concerns.

- **SSR entry-point files** using `StaticRouter`: these are SSR wrappers, not RSC server components — see the `.server.jsx` naming collision below
- **Event handlers**: `onClick`, `onChange`, `onSubmit`, etc.
- **Browser APIs**: `window`, `document`, `localStorage`, `fetch` in effects
- **Browser APIs**: `window`, `document`, `localStorage` (note: `fetch` is a Node.js global since v18 and works in Server Components — calling it directly in server context is an encouraged RSC pattern; only flag `fetch` if it is called inside a `useEffect`, which is already covered by the hooks list above)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline parenthetical here is ~220 characters — it wraps awkwardly in most renderers and buries the key point. Consider splitting it into a sub-bullet or a note block for scannability:

Suggested change
- **Browser APIs**: `window`, `document`, `localStorage` (note: `fetch` is a Node.js global since v18 and works in Server Components — calling it directly in server context is an encouraged RSC pattern; only flag `fetch` if it is called inside a `useEffect`, which is already covered by the hooks list above)
- **Browser APIs**: `window`, `document`, `localStorage`
> **Note:** `fetch` is a Node.js global since v18 (experimental until v21) and works directly in Server Components — it is an encouraged RSC data-fetching pattern. Only flag `fetch` if it is called inside a `useEffect`, which is already covered by the hooks list above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — I (Claude Code) am leaving the current inline parenthetical as-is. The substance about fetch being a Node.js global and the useEffect caveat is what users need; the surrounding bullets are similarly dense, and splitting just this one into a note block would make the list read inconsistently. Happy to revisit if rendering turns out to be a problem in a specific docs theme.

Comment thread docs/pro/react-server-components/upgrading-existing-pro-app.md Outdated
@justin808
Copy link
Copy Markdown
Member Author

Review follow-up summary

I (Claude Code) triaged the latest review comments and applied fixes in commit 3e76c27.

Addressed (1):

  • [@claude[bot]] audit checklist was missing several client-only hooks — added useLayoutEffect, useInsertionEffect, useImperativeHandle, and useSyncExternalStore to both the What to look for React hooks list and the audit grep checklist. Thread resolved.

Declined (1):

  • [@claude[bot]] suggestion to split the long fetch parenthetical into a note block — left as-is (dense inline format is consistent with the surrounding bullets). Rationale posted inline; thread left open for the reviewer.

Bot summaries (no action):

  • CodeRabbit: No actionable comments were generated
  • Greptile: 5/5 confidence, safe to merge

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

Code Review — Documentation only, low risk

Overall: This is a solid set of documentation improvements addressing legitimate gaps and inaccuracies from PR #3087. All five targeted fixes are directionally correct. A few minor issues worth addressing:


Issues

1. Audit checklist omits connect() from Redux (inconsistency)

The "What to look for" section lists Redux connect() as a pattern requiring 'use client', but the audit checklist search string does not include connect. Developers following the checklist mechanically could miss existing connect() usages.

Suggested addition to the checklist search string:
```
..., ReactOnRails.authenticityToken, connect(
```
(Using connect( rather than connect avoids false positives like connection.)


2. resolve.fallback: false comment accuracy

The new comment says "no require() call emitted" — this is closer to correct than the old "provide empty modules" but is still slightly misleading. Webpack's resolve.fallback: false means no polyfill is provided; the require call itself may still appear in the bundle output (it just resolves to an empty/unresolvable module rather than a shim). More accurate phrasing:

// tells webpack: do not polyfill this module (import resolves to nothing)

3. additionalContext example — missing reference to where the config object is used

The code example shows:
```js
const config = {
// ... other options
additionalContext: { MessageChannel },
};
```
…but doesn't show how config is passed to the renderer (e.g., is it exported? passed to a constructor?). A reader unfamiliar with the node renderer API won't know what to do with this object. Either link to the node renderer config docs or add a one-line context comment such as // export this config from node-renderer.js.


Nits (no action required)

  • The fetch bullet in "Browser APIs" is now significantly longer than the other bullets. It's accurate, but consider moving the explanation to a follow-up note/blockquote so the bullet list stays scannable.
  • useId (already in the original list, not changed here) can technically be used in Server Components per the React docs — it's not strictly client-only. This is pre-existing and being conservative is fine for a migration guide, but worth a future note.

Correct / approved changes

  • runs-on: ubuntu-latest addition makes the CI YAML copy-paste valid
  • ✅ MessageChannel section reorder (recommended → fallback) is the right structure
  • ✅ Synchronous-delivery caveat preserved in the BannerPlugin fallback section
  • useLayoutEffect, useInsertionEffect, useImperativeHandle, useSyncExternalStore additions to the hooks list are all legitimately client-only
  • ReactOnRails.authenticityToken() addition to the checklist is accurate

Before proceeding to Step 1:

- [ ] Search your component source files for `useState`, `useEffect`, `useContext`, `useSelector`, `useDispatch`, `useTransition`, `useDeferredValue`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`
- [ ] Search your component source files for `useState`, `useEffect`, `useLayoutEffect`, `useInsertionEffect`, `useContext`, `useRef`, `useImperativeHandle`, `useReducer`, `useCallback`, `useMemo`, `useTransition`, `useDeferredValue`, `useId`, `useSyncExternalStore`, `useOptimistic`, `useFormStatus`, `useSelector`, `useDispatch`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`, `ReactOnRails.authenticityToken`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "What to look for" section above flags Redux connect() as requiring 'use client', but connect( is missing from this search string. Developers following the checklist could miss connect() wrappings.

Suggested change
- [ ] Search your component source files for `useState`, `useEffect`, `useLayoutEffect`, `useInsertionEffect`, `useContext`, `useRef`, `useImperativeHandle`, `useReducer`, `useCallback`, `useMemo`, `useTransition`, `useDeferredValue`, `useId`, `useSyncExternalStore`, `useOptimistic`, `useFormStatus`, `useSelector`, `useDispatch`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`, `ReactOnRails.authenticityToken`
- [ ] Search your component source files for `useState`, `useEffect`, `useLayoutEffect`, `useInsertionEffect`, `useContext`, `useRef`, `useImperativeHandle`, `useReducer`, `useCallback`, `useMemo`, `useTransition`, `useDeferredValue`, `useId`, `useSyncExternalStore`, `useOptimistic`, `useFormStatus`, `useSelector`, `useDispatch`, `connect(`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`, `ReactOnRails.authenticityToken`

Using connect( (with the opening paren) avoids false positives like connection or connected.


```js
// In serverWebpackConfig.js -- tells webpack to provide empty modules
// In serverWebpackConfig.js -- tells webpack to omit these modules (no require() call emitted)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolve.fallback: false means webpack will not resolve the module to any polyfill — but the require call may still exist in the bundle output (it just resolves to an empty/unresolvable module rather than a shim). The phrase "no require() call emitted" overstates the effect.

Suggested change
// In serverWebpackConfig.js -- tells webpack to omit these modules (no require() call emitted)
// In serverWebpackConfig.js -- tells webpack to omit the polyfill (import resolves to nothing; no shim bundled)

// In your node-renderer.js config
const { MessageChannel } = require('node:worker_threads');

const config = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The snippet shows config being built but doesn't show how it's wired into the renderer. A reader unfamiliar with the node renderer API won't know what to do with this object. Consider adding a line like:

module.exports = config; // export from node-renderer.js

or a link to the node renderer configuration reference so the example is self-contained.

justin808 and others added 3 commits April 17, 2026 21:42
Applies the documentation review comments surfaced against PR #3087:

- Add missing `runs-on: ubuntu-latest` to the CI workflow example in
  node-renderer/basics.md so the snippet is copy-paste valid.
- Correct the `resolve.fallback: false` inline comment in
  rsc-troubleshooting.md to match the surrounding explanation
  ("omit the module" rather than "provide empty modules").
- Expand the upgrading-existing-pro-app audit checklist to include the
  React, React DOM, router, and ReactOnRails hook names that were
  listed in "What to look for" but missing from the checklist.
- Reorder the MessageChannel troubleshooting section to lead with the
  recommended `additionalContext` fix and demote BannerPlugin to a
  fallback, so users encounter the preferred option first.
- Clarify `fetch` under "Browser APIs": it is a Node.js global since v18
  and works in Server Components; only flag it when called inside a
  `useEffect` (already covered by the hooks list).

Fixes #3155

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add useLayoutEffect, useInsertionEffect, useImperativeHandle, and
useSyncExternalStore to the React hooks list and the audit grep
checklist. These hooks are client-only and would fail at runtime
with "hook is not a function" in a mis-classified Server Component.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add `connect(` to the RSC audit grep checklist so it stays
  consistent with the "What to look for" section (which already lists
  Redux `connect()` as requiring `'use client'`). The `(` suffix
  avoids false positives like `connection`/`connected`.
- Replace the misleading "no require() call emitted" phrasing for
  `resolve.fallback: false` with "imports resolve to nothing; no shim
  bundled" — webpack resolves the import to an empty module rather
  than suppressing the require() entirely.
- Make the `additionalContext` MessageChannel example self-contained
  by showing `module.exports = config;` and linking to the node
  renderer JS configuration reference.
@justin808 justin808 force-pushed the jg/3155-rsc-docs-followup branch from 3e76c27 to 6ba6295 Compare April 18, 2026 07:49
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

test

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

NOTE: This is a placeholder - full review being posted in separate comment. Please ignore this comment.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

Change Log

All notable changes to this project's source code will be documented in this file. Items under Unreleased is upcoming features that will be out in the next version.

This is the unified changelog for both React on Rails (open source) and React on Rails Pro.
Pro-specific changes are tagged inline with [Pro]. For pre-monorepo Pro history (versions 4.0.0-rc.15 and earlier), see the archived Pro CHANGELOG.

Migration instructions for the major updates can be found here. Some smaller migration information can be found here.

Want to Save Time Updating?

If you need help upgrading react_on_rails, webpacker to shakapacker, or JS packages, contact justin@shakacode.com. We can upgrade your project and improve your development and customer experiences, allowing you to focus on building new features or fixing bugs instead.

For an overview of working with us, see our Client Engagement Model article and how we bill for time.

If you think ShakaCode can help your project, click here to book a call with Justin Gordon, the creator of React on Rails and Shakapacker.

Contributors

Please follow the recommendations outlined at keepachangelog.com. Please use the existing headings and styling as a guide.
After a release, run /update-changelog in Claude Code to analyze commits, write entries, and create a PR. Alternatively, run bundle exec rake update_changelog to add version headers only (you must write entries manually).

Versions

Unreleased

Fixed

  • Client startup now recovers if initialization begins during interactive after DOMContentLoaded already fired: React on Rails now still initializes the page when the client bundle starts in the browser timing window after DOMContentLoaded but before the document reaches complete. Fixes Issue 3150. PR 3151 by ihabadham.
  • Doctor accepts TypeScript server bundle entrypoints: react_on_rails:doctor now resolves common source entrypoint suffixes (.js, .jsx, .ts, .tsx, .mjs, .cjs) before warning that the server bundle is missing, preventing false positives when apps use server-bundle.ts. PR 3111 by justin808.
  • Doctor no longer fails custom projects for a missing generated bin/dev: react_on_rails:doctor now downgrades a missing official React on Rails bin/dev launcher from an error to a warning and adds explicit guidance when a custom ./dev script is detected, so custom projects can pass diagnostics when their development setup is intentional. Fixes Issue 3103. PR 3117 by justin808.

16.6.0 - 2026-04-09

Removed

  • Removed immediate_hydration configuration and parameter: The immediate_hydration config option, helper parameter, data-immediate-hydration HTML attribute, and redux_store immediate_hydration: keyword argument have been completely removed. Immediate hydration is now always enabled for React on Rails Pro users and disabled for non-Pro users, with no per-component override. Remove any immediate_hydration references from your initializer and helper calls. Passing immediate_hydration: to react_component / react_component_hash is now ignored, and passing it to stream_react_component logs a warning. This change also fixes HTML attribute escaping for redux store names to prevent attribute injection from unsafe store keys. Closes Issue 2142.
    PR 2834 by
    justin808.

Added

  • [Pro] Auto-resolve renderer password from ENV: setup_renderer_password now falls back to ENV["RENDERER_PASSWORD"] when neither config.renderer_password nor a URL-embedded password is set, aligning Rails-side behavior with the Node Renderer defaults. Blank values (nil or "") are treated identically and fall through the full resolution chain: config → URL → ENV. PR 2921 by justin808.
  • Interactive mode prompt for create-react-on-rails-app: Running npx create-react-on-rails-app without --pro or --rsc now shows an interactive prompt to choose between Standard, Pro, and RSC modes (default: RSC recommended). Explicit flags skip the prompt, and non-interactive environments fall back to standard mode automatically. PR 3063 by justin808.
  • [Pro] Configurable HTTP keep-alive timeout for node renderer connections: Added renderer_http_keep_alive_timeout configuration option (default: 30s) to control how long idle persistent HTTP/2 connections to the node renderer are kept alive, preventing SSR failures from stale connections. PR 3069 by justin808.
  • [Pro] react_on_rails:pro now automates Pro and RSC Pro upgrades: Added first-class --rsc-pro install mode, automatic react_on_rails -> react_on_rails_pro Gemfile and package swaps, and frontend import rewrites to streamline existing app upgrades. PR 2822 by justin808.

Improved

  • [Pro] Clearer node renderer request context in exception messages: Exception formatting now uses a generic Request: label instead of render-specific wording, so /upload-assets failures and other non-render paths report the actual request context more clearly. PR 2877 by AbanoubGhadban.
  • [Pro] Cleaner node renderer diagnostic output: Invalid render-request diagnostics no longer redundantly list renderingRequest in the bodyKeys output since it is already reported via the Received type: line, and renderer_http_keep_alive_timeout documentation now recommends setting it shorter than the node renderer's server-side idle timeout. PR 3086 by justin808.
  • Doctor enforces strict version constraints: react_on_rails:doctor now escalates non-exact gem and npm version specs (^, ~, >=) from warnings to errors, matching the runtime VersionChecker behavior. Wildcard checks now also cover Pro packages (react-on-rails-pro, react_on_rails_pro). PR 3070 by justin808.
  • Error messages recommend doctor: Runtime version-check crashes, configuration validation errors, and autobundling errors now suggest running bundle exec rake react_on_rails:doctor for diagnostics and bundle exec rake react_on_rails:sync_versions WRITE=true to fix version mismatches. PR 3070 by justin808.
  • sync_versions handles range specs: Version ranges like ^16.5.0, ~16.5.0, and >=16.5.0 are now parsed and rewritten to the exact expected version instead of being skipped as unsupported. When FIX=true is set, doctor auto-runs sync_versions to fix detected mismatches. PR 3070 by justin808.
  • [Pro] Improved node renderer error messages for malformed render requests: Added early validation for missing or invalid renderingRequest payloads on the render endpoint, returning actionable 400 messages that include received type, body keys, and likely causes (truncation, malformed multipart, content-length mismatch). PR 3068 by justin808.
  • react_on_rails:doctor now prefers runtime configuration: Doctor now reads loaded ReactOnRails.configuration values before falling back to initializer parsing, improving diagnostics for customized SSR and NodeRenderer setups. PR 2823 by justin808.
  • Fresh app onboarding for create-react-on-rails-app: New apps now land on a generated root page with links to the local demos, docs, OSS vs Pro guidance, the Pro quick start, and the marketplace RSC demo. bin/dev opens that page on first boot, --rsc scaffolds the same fresh-app experience, and the generated app records step-by-step educational git commits for each scaffold phase. PR 2849 by justin808.

Fixed

  • Pin third-party npm dependency versions in generator: All third-party npm dependencies installed by the react_on_rails:install generator and bin/switch-bundler are now pinned to ^major.0.0 version ranges, preventing peer dependency conflicts from uncontrolled major version bumps. Fixes CI breakage caused by @rspack/plugin-react-refresh@2.0.0 requiring @rspack/core@^2.0.0-0 while @rspack/core latest was still 1.7.11. SWC dependency pins match Shakapacker's own version constraints. Closes Issue 3082. PR 3083 by ihabadham.
  • [Pro] Fixed TanStack Router SSR hydration mismatches in the async path: Client hydration now restores server match data before first render, uses RouterProvider directly to match the server-rendered tree, and stops the post-hydration load when a custom router.options.hydrate callback fails instead of continuing with partially hydrated client state. PR 2932 by justin808.
  • [Pro] Fixed infinite fork loop when node renderer worker fails to bind port: When a worker failed during app.listen() (e.g., EADDRINUSE), the master previously reforked unconditionally, causing an infinite fork/crash loop that consumed CPU and filled logs. Workers now send a WORKER_STARTUP_FAILURE IPC message to the master before exiting; the master sets an abort flag and exits with a clear error message instead of reforking. Scheduled restarts and runtime crashes continue to refork as before. PR 2881 by justin808.
  • [Pro] Fixed Pro generator multiline and template-literal rewrites: The Pro install generator now correctly handles multiline non-parenthesized gem "react_on_rails" declarations while preserving trailing options, and correctly rewrites module specifiers around template literals by preserving escaped sequences and detecting multiline template-literal starts after a closed inline template. PR 2918 by justin808.
  • [Pro] Fixed SSR failures from stale persistent HTTP/2 connections to the node renderer: When idle connections became stale (closed by the node renderer but still considered active by the Ruby side), render requests could be truncated mid-flight, producing confusing FST_ERR_CTP_INVALID_CONTENT_LENGTH and "INVALID NIL or NULL result for rendering" errors. The new renderer_http_keep_alive_timeout config (default: 30s) prevents this by closing idle connections before they go stale. Content-Length mismatches now produce specific diagnostic messages instead of generic errors, and sensitive field names are filtered from diagnostic output. Fixes Issue 3071. PR 3069 by justin808.
  • Legacy Shakapacker migrations are more resilient: react_on_rails:install now falls back cleanly when the package_json gem is unavailable, installs only missing JS packages through the detected package manager, and auto-switches legacy JSX-in-.js apps to Babel when needed. PR 2901 by justin808.
  • New-app root-route generation is more robust: Generator root-route detection is now centralized, duplicate route insertion is avoided, and home-page generation warns instead of failing when config/routes.rb is missing or unexpected. PR 2891 by justin808.
  • bin/dev now exits quietly on Ctrl-C: The process manager and generated Shakapacker watcher wrapper now treat interrupt-driven shutdown as a clean exit, avoiding Ruby backtraces during local development. PR 2652 by justin808.
  • bin/dev browser auto-open now waits for route readiness: --open-browser and --open-browser-once now poll the target app route and open the browser only after receiving a success or redirect response, reducing premature opens during boot. PR 2885 by justin808.

16.5.1 - 2026-03-27

Fixed

  • [Pro] TanStack Router: removed dependency on internal router.ssr flag: Server-side rendering no longer
    sets the internal router.ssr property (unnecessary since React effects don't run during renderToString).
    Client-side legacy hydration path now uses the correct { manifest: undefined } shape matching TanStack Router's
    internal $_TSR contract instead of a bare true boolean, improving forward compatibility. The recommended
    RouterClient/ssrRouter hydration path was already free of this dependency.
    Fixes Issue 2647. PR 2833 by justin808.
  • [Pro] Fixed missing rake tasks in published gem: The Pro gemspec excluded lib/tasks/ from packaged files, so all react_on_rails_pro:* rake tasks (verify_license, pre_stage_bundle_for_node_renderer, copy_assets_to_remote_vm_renderer, process_v8_logs) were unavailable after gem install. PR 2872 by justin808.
  • [Pro] Fixed bundle duplication in remote node renderer asset uploads: When RSC support is enabled, running rake react_on_rails_pro:copy_assets_to_remote_vm_renderer no longer duplicates bundle JS files across bundle directories. Previously, both the server bundle and RSC bundle were copied into every target directory; now each bundle is placed only in its own directory while shared assets (manifests, stats) are correctly distributed to all. PR 2768 by AbanoubGhadban. Fixes Issue 2766.

16.5.0 - 2026-03-25

Added

  • create-react-on-rails-app --pro support: Added explicit --pro mode to the CLI, including react_on_rails_pro gem installation and generator wiring for Pro-only setup (without requiring --rsc). PR 2818 by justin808.
  • Global prerender env override: Added REACT_ON_RAILS_PRERENDER_OVERRIDE=true|false to force prerender behavior globally (env > component option > initializer default), useful for CI/test environments without an SSR server. PR 2816 by justin808.
  • react_on_rails:sync_versions rake task: Added a version synchronizer that aligns npm package versions (react-on-rails, react-on-rails-pro, react-on-rails-pro-node-renderer) with loaded gem versions. Runs in dry-run mode by default; use WRITE=true to apply changes. PR 2797 by justin808.
  • Pro/RSC setup checks in react_on_rails:doctor: Extended doctor diagnostics with Pro Setup (initializer, renderer mode, base-package import scanning) and RSC checks (renderer mode, payload route, bundler config, React version, Procfile RSC watcher). Sections are skipped for OSS-only installs. PR 2674 by ihabadham.

Changed

  • [Pro] Canonical env var for worker count is now RENDERER_WORKERS_COUNT. The previous NODE_RENDERER_CONCURRENCY is still supported as a fallback. Worker count validation now accepts explicit 0 for single-process mode and warns on invalid values. PR 2611 by justin808.
  • [Pro] Migrated from Async::Variable to Async::Promise: The streaming helper internals now use Async::Promise for async v2.29+ compatibility while preserving pre-first-chunk error propagation behavior. PR 2832 by justin808. Fixes Issue 2563.

Improved

  • Smoother create-react-on-rails-app and install generator flows: Fresh app scaffolding now runs non-interactively with --force, preserves the selected package manager, normalizes pnpm projects, auto-replaces stock bin/dev, and warns (instead of failing) on dirty worktrees. Post-install output updated with db:prepare step and current docs URL. PR 2650 by justin808.
  • Pro upgrade hint after install: Running rails g react_on_rails:install now prints a Pro upgrade hint with docs link. Suppressed when --pro or --rsc flags are used. PR 2642 by justin808.

Fixed

  • Preserve runtime env vars across Bundler.with_unbundled_env: Fixed PORT and SHAKAPACKER_DEV_SERVER_PORT being lost when ProcessManager runs foreman/overmind inside Bundler.with_unbundled_env, breaking auto-detected ports from PortSelector. Env vars are now captured before the unbundled block and passed explicitly to system(). PR 2836 by ihabadham.
  • Fix doctor prerender check and ExecJS display for Pro/RSC apps: uses_prerender_in_views? now detects Pro streaming helpers (stream_react_component, cached_stream_react_component, rsc_payload_react_component) that implicitly enable prerender. Server rendering engine display now correctly detects NodeRenderer configuration from the Pro initializer. PR 2773 by ihabadham.
  • Fix doctor false positives for custom layouts: react_on_rails:doctor now resolves package.json from node_modules_location config (instead of assuming repo root) and discovers webpack/rspack configs across common custom locations. Missing bundler config downgraded from error to contextual warning. PR 2612 by justin808.
  • [Pro] Require RENDERER_PASSWORD in production-like Node Renderer environments: The Pro Node Renderer now fails fast when started without a truthy RENDERER_PASSWORD outside development/test, masks module-load password defaults in diagnostic logs, warns when buildConfig({ password: undefined }) preserves the env/default password, and clarifies the Ruby-side initializer requirement. PR 2829 by justin808.

Breaking Changes

  • [Pro] RENDERER_PASSWORD now required in production-like environments: Existing staging/production deployments using NodeRenderer without a password will fail to start after upgrading. Set RENDERER_PASSWORD in the environment and configure config.renderer_password = ENV.fetch("RENDERER_PASSWORD") in your Rails initializer before upgrading. PR 2829 by justin808.
  • [Pro] Minimum async gem version bumped to 2.29: The streaming helper now requires async >= 2.29 (previously >= 2.6) due to the migration from Async::Variable to Async::Promise. If your Gemfile pins the async gem below 2.29, you will need to update it before upgrading React on Rails Pro. Run bundle update async to pick up the new minimum.
    PR 2832 by justin808.

16.4.0 - 2026-03-16

Fixed

  • Install generator now handles TypeScript and rspack bundler configs correctly: Projects using Shakapacker 9.4+ with TypeScript configs (.ts) were incorrectly prompted to confirm config replacement during rails generate react_on_rails:install, because the installer didn't recognize the ESM-style stock configs. The installer and react_on_rails:doctor now detect all config variants (webpack/rspack, JS/TS), use the correct replacement template for each, and show accurate bundler-specific diagnostic messages. PR 2567 by AbanoubGhadban.
  • Show incomplete install message after Shakapacker failure: The react_on_rails:install generator now tracks when automatic Shakapacker setup fails and emits an explicit "installation incomplete" warning with manual recovery steps, instead of the misleading "Successfully Installed" banner. PR 2613 by justin808. Fixes Issue 2600.
  • Ruby 3.4 compatibility for heredocs: Replaced legacy strip_heredoc usage with native squiggly heredocs (<<~) and removed redundant chaining where indentation is already normalized by Ruby. PR 2599 by justin808.
  • Fix install generator load path for ReactOnRails::GitUtils: Added an explicit require "react_on_rails/git_utils" so generator execution does not rely on broader app boot side effects for this constant to be available. PR 2599 by justin808.
  • server_render_js now handles non-Error throws safely: Defensive error serialization now supports thrown primitives and null values without raising secondary TypeError exceptions while building SSR error payloads. PR 2599 by justin808.
  • Clean stale webpack config on --rspack install: Running rails g react_on_rails:install --rspack now removes leftover config/webpack/ files when switching from webpack to rspack, preventing Shakapacker deprecation warnings. Only known stock/generated webpack configs are removed; custom files are preserved with a warning. PR 2597 by justin808. Fixes Issue 2549.
  • Fixed bin/setup failing on pnpm workspace member directories: bin/setup now checks for the presence of pnpm-lock.yaml before running pnpm install --frozen-lockfile, preventing failures in workspace member directories (e.g., spec/dummy) where dependencies are managed by the workspace root. PR 2477 by justin808.
  • CSS module SSR fixes for rspack: Fixed CSS module class name divergence between client and server bundles when using rspack. Server webpack config now filters rspack's cssExtractLoader in addition to mini-css-extract-plugin, uses spread syntax to preserve existing CSS module options when setting exportOnlyLocals: true, and adds null guards against undefined entries in rule.use arrays. Note: exportOnlyLocals: true is no longer applied when cssLoader.options.modules is falsy (disabled), which is the correct behavior but a change from prior versions. PR 2489 by justin808.
  • Fixed private_output_path not configured on fresh Shakapacker installs: When running rails g react_on_rails:install without pre-existing Shakapacker configuration, private_output_path: ssr-generated was left commented out in the generated config/shakapacker.yml. The generator now detects whether Shakapacker was just installed and passes a shakapacker_just_installed flag to BaseGenerator, which uses force: true when copying the config template to ensure the RoR version replaces Shakapacker's default. PR 2411 by ihabadham.
  • Install generator --pretend now behaves as a safe dry run: react_on_rails:install previously executed real Shakapacker setup commands (bundle add, bundle install, and rails shakapacker:install) and could crash on File.chmod because Thor pretend mode does not create files. --pretend now skips automatic Shakapacker installation and raw chmod calls so dry-run previews complete without side effects. PR 2536 by justin808.
  • Generator test defaults now consistently use build_test_command + TestHelper, with Minitest support: Fresh installs now enable config.build_test_command and wire React on Rails TestHelper for RSpec and Minitest, while generated config/shakapacker.yml sets test compile: false to avoid mixed compilation strategies by default. Doctor now validates helper wiring per framework (including mixed RSpec+Minitest apps), detects separate vs shared test/development output-path workflows, and supports FIX=true auto-fixes for the recommended setup path. Added bin/dev test-watch with auto|full|client-only modes so test watching is easier to run consistently. bin/dev help and testing docs now explicitly document both the recommended separate-output workflow and the advanced static-only shared-output workflow, including migration from manual watcher commands. PR 2513 by justin808.
  • bin/dev hook script path resolution without Rails.root: Fixed resolve_hook_script_path failing in early startup (before Rails is initialized) by adding a project_root helper that resolves the project root via BUNDLE_GEMFILE dirname or Dir.pwd when Rails.root is unavailable. PR 2568 by ihabadham. Fixes Issue 2438.
  • Rspack generator config path: Fixed --rspack generator placing config files under config/webpack/ instead of config/rspack/, causing Shakapacker deprecation warnings. All config file destinations are now dynamically remapped based on the active bundler, and using_rspack? auto-detects rspack projects for standalone generators (react_on_rails:rsc, react_on_rails:pro). PR 2417 by justin808.
  • Precompile hook load-based execution path: Fixed the precompile hook not executing its tasks when invoked via load (as used by bin/dev) instead of direct script execution. Added a shared run_precompile_tasks entry point that works regardless of invocation method. PR 2419 by justin808. Fixes Issue 2195.
  • create-react-on-rails-app validation improvements: Tightened CLI validation to enforce Rails 7+ and app-name leading-letter requirements, with clearer error messages for invalid names containing hyphens or underscores. PR 2577 by justin808.
  • Install @babel/preset-react for non-SWC generator installs: The generator now installs @babel/preset-react as a dev dependency when the project uses Babel (not SWC) as the transpiler, fixing JSX compilation errors on fresh installs with older Shakapacker defaults. PR 2421 by justin808.
  • Fix react_on_rails:doctor false positives for Pro/SWC setups: Doctor now recognizes react-on-rails-pro npm package for presence and version sync checks, skips @babel/preset-react check when SWC is the transpiler, and fixes a nil-safety bug where missing "dependencies" in package.json silently dropped devDependencies from checks. PR 2581 by ihabadham.
  • Fixed ScoutApm instrumentation depending on Gemfile ordering. ScoutApm instrumentation for react_component, react_component_hash, and exec_server_render_js was previously installed at gem load time using defined?(ScoutApm) guards, which meant it was silently skipped if scout_apm appeared after react_on_rails in the Gemfile, and produced noisy INFO log messages if it appeared before (since ScoutApm wasn't yet initialized). Moved instrumentation into an initializer that runs after scout_apm.start, ensuring it works regardless of gem ordering and only after ScoutApm is fully configured. PR 2442 by tonyta.
  • RSC WebpackLoader with SWC transpiler: Fixed RSC WebpackLoader never being injected when using SWC (Shakapacker's default transpiler). The RSC config only handled array-based rule.use (Babel) but SWC uses a function-based rule.use, so 'use client' files passed through untransformed into the RSC bundle. Now handles both array and function loader declarations. PR 2476 by AbanoubGhadban.
  • RSC Generator Layout Wiring: Fixed MissingEntryError on fresh RSC installs where HelloServerController fell back to Rails' application.html.erb (which uses javascript_pack_tag "application" that is not created by the RSC flow). The generator now always copies hello_world.html.erb, HelloServerController explicitly uses layout "hello_world", and post-install output now shows stream_react_component for RSC installs. PR 2429 by justin808.
  • Fixed string values interpolated into generated JS code without proper escaping. All string values (component names, DOM IDs, Redux store names) embedded in server-rendering JavaScript now use .to_json instead of unescaped single-quoted interpolation, preventing potential JS breakage from special characters. PR 2440 by AbanoubGhadban.
  • Precompile Hook Detection: Fixed shakapacker_precompile_hook_configured? always returning false for apps created with the React on Rails generator. The detection logic only matched the rake task pattern (react_on_rails:generate_packs) but the generator template uses the Ruby method (generate_packs_if_stale). Now correctly detects both patterns, including resolving script file contents. PR 2282 by ihabadham.
  • Precompile Hook Self-Guard for HMR: Added self-guard to the generator template's bin/shakapacker-precompile-hook to prevent duplicate execution in HMR mode where two webpack processes (client dev-server + server watcher) each trigger the hook. The script now exits early when SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true is set by bin/dev, regardless of Shakapacker version. The version warning is now smarter: it only warns for hooks that lack the self-guard or use direct commands. Existing users: add exit 0 if ENV["SHAKAPACKER_SKIP_PRECOMPILE_HOOK"] == "true" near the top of your bin/shakapacker-precompile-hook script. PR 2388 by justin808.
  • Fix generator inheriting BUNDLE_GEMFILE from parent process: The react_on_rails:install generator now wraps bundler commands with Bundler.with_unbundled_env to prevent inheriting BUNDLE_GEMFILE from the parent process, which caused "injected gems" conflicts when running generators inside a bundled context. PR 2288 by ihabadham.
  • [Pro] Fix streaming deadlock, exception masking, and cache poisoning on client disconnect: Fixed async streaming bugs where client disconnect could cause deadlocks, mask producer exceptions, or cache partial results. PR 2562 by AbanoubGhadban.
  • [Pro] Handle HTTPX error responses when fetching dev-server bundle/assets for upload: During development startup races, get_form_body_for_file could receive HTTPX::ErrorResponse and still call response.body, causing an unexpected crash path. The request layer now raises ReactOnRailsPro::Error with HTTPX error details before body access and includes regression tests for local path, HTTP success, and HTTP error cases. PR 2532 by justin808.
  • [Pro] Fix streaming SSR hangs and silent error absorption in RSC payload injection: Fixed two related issues: (1) streaming SSR renders hanging forever when errors occur because Node.js stream.pipe() doesn't propagate errors or closure from source to destination, and (2) errors in the RSC payload injection pipeline being silently absorbed, preventing them from reaching error reporters like Sentry. Introduced a shared safePipe utility and used 'close' events as reliable termination signals across the streaming pipeline (Node renderer, RSC payload injection, transform streams, and Ruby async task). Also added a Ruby safety net to prevent Rails request hangs when async rendering tasks raise before the first chunk. PR 2407 by AbanoubGhadban.
  • [Pro] Node renderer duplicate error reports for render failures: Fixed duplicate errorReporter.message notifications when unexpected exceptions occurred in handleRenderRequest. The handler now returns an error ResponseResult instead of rethrowing, so the same failure is not reported again by worker.ts while still returning a 400 response. PR 2531 by justin808.
  • [Pro] Fix RSC payload JSON corruption from Rails view annotations in development: RSC payload responses were rendered through an HTML template, so when annotate_rendered_view_with_filenames was enabled, Rails wrapped NDJSON chunks with HTML comments and broke client-side JSON.parse. The payload endpoint now renders the template in text format and serves application/x-ndjson, and a request spec covers the annotated-view scenario. If you override custom_rsc_payload_template, ensure it resolves to a text or format-neutral template (for example, .text.erb) rather than .html.erb. When RSC support is enabled, startup now also warns if Rack::Deflater is present, because response-transforming middleware can interfere with ActionController::Live NDJSON streaming. PR 2535 by justin808.
  • [Pro] Fix StreamResponse status fallback for non-streaming errors: Fixed StreamRequest#process_response_chunks not detecting error responses when status delegation raises NoMethodError, which masked the original HTTPX error path. PR 2416 by justin808.
  • [Pro] Fix empty-string license plan mismatch between Ruby and Node: Aligned Node checkPlan with Ruby check_plan so plan: "" is treated as invalid in both runtimes. Previously, an empty-string plan passed validation in Node but failed in Ruby. PR 2566 by AbanoubGhadban.
  • [Pro] Fixed buildVM promise cleanup ordering in the node renderer. buildVM() cleanup now runs via promise chaining after vmCreationPromises.set(), preventing failed synchronous VM builds from leaving stale rejected promises that block retries for the same bundle path. PR 2484 by justin808.
  • [Pro] Boot failure when only react_on_rails_pro is listed in the Gemfile. react_on_rails_pro.rb never explicitly required react_on_rails, relying on Bundler.require to auto-load it via the user's Gemfile. When installation docs were updated to direct users to only add react_on_rails_pro, two errors surfaced on boot: NoMethodError: undefined method 'strip_heredoc' (from license_public_key.rb) and NoMethodError: undefined method 'configure' for module ReactOnRails (from config/initializers/react_on_rails.rb). Fixed by explicitly requiring react_on_rails in react_on_rails_pro.rb, completing the same design the JS package split already established for npm. PR 2492 by ihabadham.
  • [Pro] Sentry SDK v9/v10 compatibility: The node renderer Sentry integration now supports @sentry/node v9 and v10. Replaced @sentry/types import (no longer a transitive dependency in v9+) and widened peer dependency range from <9.0.0 to <11.0.0. PR 2434 by alexeyr-ci2.
  • [Pro] Fixed node renderer upload race condition causing ENOENT errors and asset corruption during concurrent requests. Concurrent multipart uploads (e.g., during pod rollovers) all wrote to a single shared path (uploads/<filename>), causing file overwrites, ENOENT errors, and cross-contamination between requests. Each request now gets its own isolated upload directory (uploads/<uuid>/), eliminating all shared-path collisions. PR 2456 by AbanoubGhadban.
  • [Pro] Fixed node renderer race condition between /upload-assets and render requests writing to the same bundle directory. The /upload-assets endpoint used a global lock while render requests used per-bundle locks, so both could write to the same bundle directory concurrently, risking asset corruption. Now both endpoints share the same per-bundle lock key. Also switched parallel bundle processing from Promise.all to Promise.allSettled to prevent the onResponse cleanup hook from deleting uploaded files while in-flight copies are still reading from them. PR 2464 by AbanoubGhadban.
  • [Pro] Fixed TS2769 build error in node renderer onFile callback. Removed explicit this: FastifyRequest annotation that was incompatible with @fastify/multipart type definitions, fixing pnpm build and pnpm install failures on fresh runners. PR 2469 by AbanoubGhadban.
  • [Pro] Fixed RSC rendering corruption when props contain $-patterns. Props containing $` (dollar-backtick), $', or $& — common in markdown with bash variables — caused String.prototype.replace() to interpret these as special replacement patterns, corrupting the generated JavaScript and hanging the RSC payload stream. Fixed by using a function replacement callback which disables all $-pattern interpretation. PR 2440 by AbanoubGhadban.
  • [Pro] Fixed RSC stream tee backpressure deadlock for large payloads. Replaced pipe()-based stream teeing with manual on('data') + push() forwarding to prevent deadlocks when RSC payloads exceed the 32KB default highWaterMark buffer, which caused the stream to hang indefinitely. PR 2444 by AbanoubGhadban.

Improved

  • Auto-install react_on_rails_pro gem for --rsc/--pro generator flags: Running rails g react_on_rails:install --rsc or --pro now automatically installs the react_on_rails_pro gem via bundle add instead of only printing an error, matching how Shakapacker is handled in the same generator. PR 2439 by justin808.
  • create-react-on-rails-app validation and test coverage: Tightened app name validation (must start with a letter), added Rails 7.0+ prerequisite validation, and expanded validator/setup test coverage (including validateAll success path). PR 2571 by justin808.
  • Smarter duplicate registration warnings: Component and store registration now only warns when a different component or store is registered under an already-used name. Re-registering the same component (common with HMR) is silently accepted. PR 2354 by justin808.
  • [Pro] Better error messages when component is missing 'use client' with RSC. When RSC support is enabled, components without 'use client' silently crash at runtime with confusing errors. Improved error messages at multiple layers: runtime server and client bundles now include the component name and suggest adding 'use client', build-time heuristic scans for client-only patterns and emits warnings, and generated server component pack files explain the classification. PR 2403 by AbanoubGhadban.

Changed

  • Generator layout renamed: Fresh installs now generate react_on_rails_default.html.erb instead of hello_world.html.erb, and generated controllers declare layout "react_on_rails_default". The layout exists only to provide empty javascript_pack_tag and stylesheet_pack_tag calls for React on Rails auto-registration — it has no connection to the HelloWorld demo. Standalone react_on_rails:rsc upgrades now reuse an existing compatible layout when possible and otherwise create a compatible new layout without renaming user files. PR 2482 by ihabadham.
  • Clarified Pro-installation signaling for immediate hydration warnings: Updated Ruby/TypeScript warning text and related docs to state that railsContext.rorPro indicates Pro gem installation (not license validity), and renamed immediate_hydration_pro_license_warning to immediate_hydration_pro_install_warning (no backward-compatible alias needed since the method had no external callers). PR 2590 by justin808.
  • [Pro] Breaking: removed legacy key-file license fallback: config/react_on_rails_pro_license.key is no longer read. Move your token to the REACT_ON_RAILS_PRO_LICENSE environment variable. A migration warning is logged at startup when the legacy file is detected and the environment variable is missing. PR 2454 by ihabadham.

Added

  • Automatic dev asset reuse for tests: When bin/dev static is running, bundle exec rspec (and Minitest) now automatically detects and reuses the fresh development assets instead of running a separate build_test_command. The TestHelper reads config/shakapacker.yml, verifies the dev manifest is static-mode (not HMR) and fresh, then temporarily overrides Shakapacker's test config to point at the dev output. No environment variables or extra commands needed — tests "just work" with bin/dev static. HMR mode (bin/dev) continues to require separate test compilation via build_test_command or bin/dev test-watch. PR 2570 by justin808.

  • [Pro] TanStack Router SSR integration: Added createTanStackRouterRenderFunction and serverRenderTanStackAppAsync via react-on-rails-pro/tanstack-router for TanStack Router SSR with the Pro Node Renderer. Uses TanStack Router's public router.load() API for reliable async SSR. Requires rendering_returns_promises = true in Pro config. PR 2516 by justin808.

  • create-react-on-rails-app --rsc flow: Added --rsc support to npx create-react-on-rails-app so a single command can scaffold an RSC-ready app. The CLI now installs react_on_rails_pro, passes --rsc to react_on_rails:install, and points users to /hello_server after setup. PR 2430 by justin808.

  • Environment-variable-driven ports in Procfile templates: Procfile templates now use ${PORT:-3000} and ${SHAKAPACKER_DEV_SERVER_PORT:-3035} instead of hardcoded ports, enabling multiple worktrees to run bin/dev concurrently without port conflicts. Includes a PortSelector that auto-detects free ports when defaults are occupied, plus a generated .env.example documenting manual overrides. PR 2539 by ihabadham.

  • CSP nonce support for RSC streaming and console replay scripts: Added cspNonce to rails_context and threaded nonce values through Pro RSC streaming paths (server-side HTML stream injection and client-side console replay script insertion), with nonce sanitization. PR 2418 by justin808.

  • Pro and RSC generator flags: Added --pro and --rsc flags to rails g react_on_rails:install, plus standalone react_on_rails:pro and react_on_rails:rsc generators for upgrading existing apps to Pro and React Server Components. Includes idempotent setup modules, webpack config transforms, prerequisite validation, and example components. PR 2284 by ihabadham.

  • create-react-on-rails-app CLI tool: New npx create-react-on-rails-app command for single-command project setup. Phase 1 supports JavaScript and TypeScript templates with npm/pnpm, orchestrating rails new + bundle add react_on_rails + rails generate react_on_rails:install with prerequisite validation and progress output. PR 2375 by justin808.

  • Extensible bin/dev precompile pattern: New alternative approach for handling precompile tasks directly in bin/dev, providing better support for projects with custom build steps (ReScript, TypeScript), direct Ruby API access via ReactOnRails::Locales.compile, and improved version manager compatibility. PR 2349 by justin808.

  • Database setup check in bin/dev: The bin/dev command now checks database connectivity before starting the development server. This provides clear error messages when the database is missing or unavailable, instead of buried errors in the logs. Note: This adds ~1-2 seconds to startup time as it spawns a Rails runner process.

    Opt-out options (for apps without databases or when faster startup is needed):

    • CLI flag: bin/dev --skip-database-check
    • Environment variable: SKIP_DATABASE_CHECK=true bin/dev
    • Configuration: config.check_database_on_dev_start = false in config/initializers/react_on_rails.rb

    PR 2340 by justin808.

  • [Pro] Startup warning for unsafe compression middleware callbacks: Added a startup guard that detects Rack::Deflater or Rack::Brotli middleware with :if callbacks that iterate the response body via body.each, which can break streaming SSR/RSC and deadlock ActionController::Live. The warning includes the middleware source location and remediation guidance. PR 2554 by justin808.

  • [Pro] Configurable host binding for Node Renderer Fastify worker: Added a host setting (default: process.env.RENDERER_HOST || 'localhost') to control the bind address for the Pro Node Renderer. Set it to 0.0.0.0 in containerized environments where external health checks need to reach the renderer. PR 2585 by justin808.

  • [Pro] CSP nonce for immediate hydration scripts: The immediate hydration inline <script> tags now include the CSP nonce attribute, fixing browsers blocking them when strict Content Security Policy is enabled. PR 2398 by AbanoubGhadban.

  • [Pro] License verification rake task: New react_on_rails_pro:verify_license rake task for checking license status with human-readable text and JSON output (FORMAT=json) for CI/CD integration. Includes exit codes, automatic renewal warnings for licenses expiring within 30 days, and a GitHub Actions workflow example. PR 2385 by justin808.

  • [Pro] Auto-registration for Redux stores: Added stores_subdirectory configuration option (e.g., "ror_stores") for automatic Redux store registration, following the same pattern as component auto-registration via ror_components. Store files placed in ror_stores/ directories are automatically discovered, and packs are generated that call ReactOnRails.registerStore(), eliminating manual registration boilerplate. Includes auto_load_bundle parameter for the redux_store helper. PR 2346 by justin808.

16.3.0 - 2026-02-05

Changed

  • Simplified Shakapacker version handling: Removed obsolete minimum version checks (6.5.1) and example generation pinning (8.2.0). The gemspec dependency shakapacker >= 6.0 is now the only minimum version requirement, with autobundling requiring >= 7.0.0. PR 2247 by justin808.
  • [Pro] License-Optional Attribution Model: React on Rails Pro now works without a license for evaluation, development, testing, and CI/CD. A paid license is only required for production deployments. Added plan field validation to both Ruby and Node.js license validators — only "paid" plan (or no plan field for backwards compatibility) is accepted. Old free licenses are now treated as invalid. Documentation overhauled across README and LICENSE_SETUP guides; removed CI_SETUP.md (CI needs no license configuration). PR 2324 by AbanoubGhadban.

Fixed

  • Rspack configuration not applying to all environments. Fixed bin/switch-bundler crashing with Psych::AliasesNotEnabled on YAML files with anchors/aliases, and fixed the --rspack generator flag only updating the default section while leaving environment sections with webpack. Now uses regex replacement to update assets_bundler in all sections while preserving YAML structure. PR 2275 by ihabadham.
  • Precompile hook not configured when Shakapacker is pre-installed. Fixed the install generator not configuring the precompile_hook when Shakapacker was already installed before running rails generate react_on_rails:install. This caused missing component bundles during assets:precompile in production deployments. PR 2280 by ihabadham.
  • bin/dev failing with --route flag. Fixed bin/dev command failing with "Unknown argument" when the generator was run with a --route option. The generated script now correctly handles route arguments. PR 2273 by ihabadham.

Added

  • [Pro] Multiple License Plan Types: License validation now supports multiple plan types beyond "paid": startup, nonprofit, education, oss, and partner. Non-paid plan types are displayed in the license validation success message (e.g., "License validated successfully (startup license)."). Includes thread-safe caching for plan type retrieval via LicenseValidator.license_plan. PR 2334 by justin808.
  • [Pro] Node Renderer Master/Worker Exports: Added public master and worker exports to react-on-rails-pro-node-renderer package, allowing users to import from react-on-rails-pro-node-renderer/master and react-on-rails-pro-node-renderer/worker. PR 2326 by justin808.

16.2.1 - 2026-01-18

Fixed

  • bin/dev Route Argument Parsing: Fixed bin/dev command failing with "Unknown argument: hello_world" when run without arguments. The --route argument format was changed from two separate arguments to a single combined argument (--route=value). PR 2309 by K4sku.

Developer (Contributors Only)

  • Benchmarking in CI: A benchmark workflow will now run on all pushes to master, as well as PRs with benchmark or full-ci labels. PR 1868 by alexeyr-ci2.

16.2.0 - 2026-01-14

This release includes all features from the React on Rails Pro 4.0.0 release series (previously released as 4.0.0-rc.6 through 4.0.0-rc.15). Pro-specific entries are tagged with [Pro]. For pre-monorepo Pro history, see the archived Pro CHANGELOG.

Breaking Changes

  • config.immediate_hydration configuration removed: The config.immediate_hydration setting in config/initializers/react_on_rails.rb has been removed. Immediate hydration is now automatically enabled for React on Rails Pro users and automatically disabled for non-Pro users.

    Migration steps:

    • Remove any config.immediate_hydration = true or config.immediate_hydration = false lines from your config/initializers/react_on_rails.rb file
    • Pro users: No action needed - immediate hydration is now enabled automatically for optimal performance
    • Non-Pro users: No action needed - standard hydration behavior continues to work as before
    • Component-level overrides: You can still override behavior per-component using react_component("MyComponent", immediate_hydration: false) or redux_store("MyStore", immediate_hydration: true)
    • If a non-Pro user explicitly sets immediate_hydration: true on a component or store, a warning will be logged and it will be enforced to fall back to standard hydration (the value will be overridden to false)

    PR 1997 by AbanoubGhadban.

  • React on Rails Core Package: Several Pro-only methods have been removed from the core package and are now exclusively available in the react-on-rails-pro package. If you're using any of the following methods, you'll need to migrate to React on Rails Pro:

    • getOrWaitForComponent()
    • getOrWaitForStore()
    • getOrWaitForStoreGenerator()
    • reactOnRailsStoreLoaded()
    • streamServerRenderedReactComponent()
    • serverRenderRSCReactComponent()

Migration Guide:

To migrate to React on Rails Pro:

  1. Install the Pro package:

    yarn add react-on-rails-pro
    # or
    npm install react-on-rails-pro
  2. Update your imports from react-on-rails to react-on-rails-pro:

    // Before
    import ReactOnRails from 'react-on-rails';
    
    // After
    import ReactOnRails from 'react-on-rails-pro';
  3. For server-side rendering, update your import paths:

    // Before
    import ReactOnRails from 'react-on-rails';
    
    // After
    import ReactOnRails from 'react-on-rails-pro';
  4. Free or low-cost Pro licenses are available for startups, small companies, and qualifying organizations. Visit React on Rails Pro to get started, or contact justin@shakacode.com for any questions.

Note: If you're not using any of the Pro-only methods listed above, no changes are required.

  • Pro-Specific Configurations Moved to Pro Gem: The following React Server Components (RSC) configurations have been moved from ReactOnRails.configure to ReactOnRailsPro.configure:

    • rsc_bundle_js_file - Path to the RSC bundle file
    • react_server_client_manifest_file - Path to the React server client manifest
    • react_client_manifest_file - Path to the React client manifest

    Migration: If you're using RSC features, move these configurations from your ReactOnRails.configure block to ReactOnRailsPro.configure:

    # Before
    ReactOnRails.configure do |config|
      config.rsc_bundle_js_file = "rsc-bundle.js"
      config.react_server_client_manifest_file = "react-server-client-manifest.json"
      config.react_client_manifest_file = "react-client-manifest.json"
    end
    
    # After
    ReactOnRailsPro.configure do |config|
      config.rsc_bundle_js_file = "rsc-bundle.js"
      config.react_server_client_manifest_file = "react-server-client-manifest.json"
      config.react_client_manifest_file = "react-client-manifest.json"
    end

    See the React on Rails Pro Configuration docs for more details.

  • Streaming View Helpers Moved to Pro Gem: The following view helpers have been removed from the open-source gem and are now only available in React on Rails Pro:

    • stream_react_component - Progressive SSR using React 18+ streaming
    • rsc_payload_react_component - RSC payload rendering

    These helpers are now defined exclusively in the react-on-rails-pro gem.

  • Strict Version Validation at Boot Time: Applications now fail to boot (instead of logging warnings) when package.json is misconfigured with wrong versions, missing packages, or semver wildcards. Users must use exact versions in package.json (no ^, ~, >, <, * operators). Migration: Update package.json to use exact versions matching installed gem (e.g., "16.1.1" not "^16.1.1"). PR #1881 by AbanoubGhadban.

  • [Pro] Node Renderer Version Validation: Remote node renderer now validates gem version at request time. Version mismatches in development return 412 Precondition Failed (production allows with warning). Ensure react_on_rails_pro gem and @shakacode-tools/react-on-rails-pro-node-renderer package versions match. PR #1881 by AbanoubGhadban.

  • [Pro] Prerender caching for streaming: config.prerender_caching now controls caching for both streamed and non-streamed components. To disable for individual renders, pass internal_option(:skip_prerender_cache).

  • [Pro] ReactOnRailsPro::Utils#copy_assets return value: Now returns nil instead of Response object, throwing an error on failure instead. PR 422 by AbanoubGhadban.

  • [Pro] Added async gem dependency (>= 2.6) for concurrent streaming.

  • [Pro] Dropped support for EOL'd Ruby 2.7. PR 365 by ahangarha.

  • [Pro] Dropped support for React on Rails below 14.0.4. PR 415 by rameziophobia.

Added

  • Shakapacker 9.0+ Private Output Path Integration: Added automatic detection and integration of Shakapacker 9.0+ private_output_path configuration. React on Rails now automatically reads private_output_path from shakapacker.yml and sets server bundle paths, eliminating manual configuration synchronization. Includes version-aware generator templates, enhanced doctor command diagnostics for configuration validation and upgrade recommendations, and improved security with enforce_private_server_bundles option. PR 2028 by justin808.

  • Rspack Support: Added --rspack flag to react_on_rails:install generator for significantly faster builds (~20x improvement with SWC). Includes unified webpack/rspack configuration templates and bin/switch-bundler utility to switch between bundlers post-installation. PR #1852 by justin808.

  • Service Dependency Checking for bin/dev: Added optional .dev-services.yml configuration to validate required external services (Redis, PostgreSQL, Elasticsearch, etc.) are running before bin/dev starts the development server. Provides clear error messages with start commands and install hints when services are missing. Zero impact if not configured - backwards compatible with all existing installations. PR 2098 by justin808.

  • CSP Nonce Support for Console Replay: Added Content Security Policy (CSP) nonce support for the consoleReplay script generated during server-side rendering. When Rails CSP is configured, the console replay script will automatically include the nonce attribute, allowing it to execute under restrictive CSP policies like script-src: 'self'. The implementation includes cross-version Rails compatibility (5.2-7.x) and defense-in-depth nonce sanitization to prevent attribute injection attacks. PR 2059 by justin808.

  • Attribution Comment: Added HTML comment attribution to Rails views containing React on Rails functionality. The comment automatically displays which version is in use (open source React on Rails or React on Rails Pro) and, for Pro users, shows the license status. This helps identify React on Rails usage across your application. PR #1857 by AbanoubGhadban.

  • Smart Error Messages with Actionable Solutions: Added intelligent Ruby-side error handling with context-aware, actionable solutions for common issues. Features include fuzzy matching for component name typos, environment-specific debugging suggestions, color-coded error formatting, and detailed troubleshooting guides for component registration, auto-bundling, hydration mismatches, server rendering errors, and Redux store issues. PR 1934 by justin808.

  • Doctor Checks for :async Loading Strategy: Added proactive diagnostic checks to the React on Rails doctor tool to detect usage of the :async loading strategy in projects without React on Rails Pro. The feature scans view files and initializer configuration, providing clear guidance to either upgrade to Pro or use alternative loading strategies like :defer or :sync to avoid component registration race conditions. PR 2010 by justin808.

  • [Pro] React Server Components Support: Full RSC integration for Rails apps — reduce client bundle sizes and enable powerful data fetching patterns. See the tutorial. PR 422 by AbanoubGhadban.

  • [Pro] Streaming Server Rendering: stream_view_containing_react_components and stream_react_component helpers for progressive page loading. Includes console log replay, error handling during streaming (initial render and suspense boundaries), and raise_non_shell_server_rendering_errors configuration. PR 407, PR #429, PR #432 by AbanoubGhadban.

  • [Pro] Async React Component Rendering: async_react_component and cached_async_react_component helpers for concurrent component rendering. Multiple components execute HTTP requests to the Node renderer in parallel. Requires ReactOnRailsPro::AsyncRendering concern in controller. PR 2139 by AbanoubGhadban.

  • [Pro] Concurrent Streaming Performance: Concurrent draining of streamed React components using the async gem with producer-consumer pattern and bounded buffering. PR 2015 by ihabadham.

  • [Pro] License Validation System: JWT-based license validation with offline verification using RSA-256 signatures. PR #1857 by AbanoubGhadban.

  • [Pro] Improved RSC Payload Error Handling: Errors during RSC payload generation are now transferred to Rails with error messages and stack traces. PR #1888 by AbanoubGhadban.

  • [Pro] cached_stream_react_component helper for cached streaming.

  • [Pro] config.concurrent_component_streaming_buffer_size option (defaults to 64) for concurrent streaming memory buffer control.

  • [Pro] replayServerAsyncOperationLogs configuration for capturing async operation console output during SSR. PR 440 by AbanoubGhadban.

Changed

  • Shakapacker 9.0.0 Upgrade: Upgraded Shakapacker from 8.2.0 to 9.0.0 with Babel transpiler configuration for compatibility. Key changes include:

    • Configured javascript_transpiler: babel in shakapacker.yml (Shakapacker 9.0 defaults to SWC which has PropTypes handling issues)
    • Added precompile hook support via bin/shakapacker-precompile-hook for ReScript builds and pack generation
    • Configured CSS Modules to use default exports (namedExport: false) for backward compatibility with existing import styles from syntax
    • Fixed webpack configuration to process SCSS rules and CSS loaders in a single pass for better performance
      PR 1904 by justin808.
  • generated_component_packs_loading_strategy now defaults based on Pro license: When using Shakapacker >= 8.2.0, the default loading strategy is now :async for Pro users and :defer for non-Pro users. This provides optimal performance for Pro users while maintaining compatibility for non-Pro users. You can still explicitly set the strategy in your configuration. PR #1993 by AbanoubGhadban.

  • Generator Configuration Modernization: Updated the generator to enable recommended configurations by default for new applications. config.build_test_command is now uncommented and set to "RAILS_ENV=test bin/shakapacker" by default, enabling automatic asset building during tests for better integration test reliability. config.auto_load_bundle = true is now set by default, enabling automatic loading of component bundles. config.components_subdirectory = "ror_components" is now set by default, organizing React components in a dedicated subdirectory. Note: These changes only affect newly generated applications. Existing applications are unaffected and do not need to make any changes. If you want to adopt these settings in an existing app, you can manually add them to your config/initializers/react_on_rails.rb file. PR 2039 by justin808.

  • Removed Babel Dependency Installation: The generator no longer installs @babel/preset-react or @babel/preset-typescript packages. Shakapacker handles JavaScript transpiler configuration (Babel, SWC, or esbuild) via the javascript_transpiler setting in shakapacker.yml. SWC is now the default transpiler and includes built-in support for React and TypeScript. Users who explicitly choose Babel will need to manually install and configure the required presets. This change reduces unnecessary dependencies and aligns with Shakapacker's modular transpiler approach. PR 2051 by justin808.

  • [Pro] immediate_hydration auto-enabled for Pro users: The configuration option has been removed; immediate hydration is now automatically enabled for Pro users and disabled for non-Pro users. Component-level overrides still supported. PR 1997 by AbanoubGhadban.

  • [Pro] RSC rendering flow improvements: Eliminated double rendering, reduced HTTP requests, added multi-bundle upload via communication protocol v2.0.0. PR 515 by AbanoubGhadban.

  • [Pro] Node Renderer: Express to Fastify: Converted worker from Express to Fastify. PR 398 by alexeyr-ci.

  • [Pro] Fastify 5 upgrade: Default with fallback to Fastify 4 on older Node versions. PR 478 by alexeyr-ci.

  • [Pro] Pino logging: Replaced Winston, aligning with Fastify. PR 479 by alexeyr-ci.

  • [Pro] HTTP/2 Cleartext communication with Node Renderer. PR 392 by alexeyr-ci.

  • [Pro] HTTPX for Node renderer: Converted from Net::HTTP to HTTPX. PR 452 by alexeyr-ci. Upgraded to ~> 1.5. PR 520 by AbanoubGhadban.

  • [Pro] Error reporting/tracing overhaul: See the docs. PR 471 by alexeyr-ci.

  • [Pro] Added fastifyServerOptions config and set bodyLimit to 100 MB by default. PR 511 by Romex91.

  • [Pro] Renamed includeTimerPolyfills to stubTimers. Fail immediately on obsolete config options. PR 506 by alexeyr-ci.

  • [Pro] Shakapacker 8.0.0 support (drops 6.x). PR 415 by rameziophobia.

Improved

  • SWC Compiler Detection: Added intelligent detection and automatic installation of SWC transpiler packages (@swc/core and swc-loader) when the generator detects SWC configuration. For Shakapacker 9.3.0+ (where SWC is the default transpiler), required packages are now installed automatically. Includes graceful error handling and YAML parsing security improvements. PR 2135 by justin808.

  • Enhanced bin/dev Error Messages: Improved error messages when bin/dev fails by suggesting the --verbose flag for detailed debugging output. The verbose flag now properly cascades to child processes via the REACT_ON_RAILS_VERBOSE environment variable, making troubleshooting pack generation failures significantly easier. PR 2083 by justin808.

  • Automatic Precompile Hook Coordination in bin/dev: The bin/dev command now automatically runs Shakapacker's precompile_hook once before starting development processes and sets SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true to prevent duplicate execution in spawned webpack processes.

    • Eliminates the need for manual coordination, sleep hacks, and duplicate task calls in Procfile.dev
    • Users can configure expensive build tasks (like locale generation or ReScript compilation) once in config/shakapacker.yml and bin/dev handles coordination automatically
    • Includes warning for Shakapacker versions below 9.4.0 (the SHAKAPACKER_SKIP_PRECOMPILE_HOOK environment variable is only supported in 9.4.0+)
    • The SHAKAPACKER_SKIP_PRECOMPILE_HOOK environment variable is set for all spawned processes, making it available for custom scripts that need to detect when bin/dev is managing the precompile hook
    • Addresses 2091 by justin808
  • Idempotent Locale Generation: The react_on_rails:locale rake task is now idempotent, automatically skipping generation when locale files are already up-to-date. This makes it safe to call multiple times (e.g., in Shakapacker's precompile_hook) without duplicate work. Added force=true option to override timestamp checking. PR 2090 by justin808.

  • Improved Error Messages: Error messages for version mismatches and package configuration issues now include package-manager-specific installation commands (npm, yarn, pnpm, bun). PR #1881 by AbanoubGhadban.

Fixed

  • Component Registration: Fixed "component not registered" error on core react-on-rails package that could occur when components were referenced before registration completed. PR 2295 by AbanoubGhadban.

  • webpack-cli Compatibility: Fixed compatibility issue with webpack-dev-server v5 by upgrading webpack-cli from v4 to v6.0.1 and removing the deprecated @webpack-cli/serve package. Also removed deprecated https: false configuration from shakapacker.yml. PR 2291 by AbanoubGhadban.

  • Hydration Mismatch on Multiple reactOnRailsPageLoaded() Calls: Fixed hydration errors that occurred when reactOnRailsPageLoaded() was invoked multiple times for asynchronously loaded content. The fix tracks rendered components and skips re-rendering already-tracked components, while intelligently handling DOM node replacements by detecting when a node with the same ID is swapped out. Addresses issue 2210. PR 2211 by justin808.

  • TypeScript processPromise Return Type: Fixed TypeScript compilation error in serverRenderReactComponent.ts where the type checker couldn't properly narrow the union type after the isValidElement check. Added explicit type assertion to FinalHtmlResult to resolve the issue. PR 2204 by justin808.

  • connection_pool 3.0+ Compatibility: Fixed ArgumentError: wrong number of arguments when using connection_pool gem version 3.0 or later. The gem's API changed from accepting a positional hash to requiring keyword arguments. This fix ensures compatibility with both older and newer versions of connection_pool. Addresses issue 2185. PR 2125 by justin808.

  • RSpec Helper Optimization with Private SSR Directories: Fixed RSpec helper optimization bug that caused tests to run with stale server-side code when server bundles are stored in private ssr-generated/ directories. The helper now automatically monitors server bundles and other critical files, ensuring proper rebuild detection even when assets are in separate directories from the manifest. PR 1838 by justin808.

  • Pack Generation in bin/dev from Bundler Context: Fixed pack generation failing with "Could not find command 'react_on_rails:generate_packs'" when running bin/dev from within a Bundler context. The fix wraps the bundle exec call with Bundler.with_unbundled_env to prevent interception. PR 2085 by justin808.

  • bin/dev Process Manager Detection: Fixed misleading "Process Manager Not Found" error when overmind is installed but exits with a non-zero code (e.g., when a Procfile process crashes). The error message now correctly distinguishes between a missing process manager and a process manager that ran but failed. PR 2087 by justin808.

  • Doctor Command Version Mismatch Detection: Fixed false version mismatch warnings in rake react_on_rails:doctor when using beta/prerelease versions. The command now correctly recognizes that gem version 16.2.0.beta.10 matches npm version 16.2.0-beta.10 using proper semver conversion instead of string normalization that stripped prerelease identifiers. PR 2064 by ihabadham.

  • Rails 5.2-6.0 Compatibility: Fixed compatibility with Rails 5.2-6.0 by adding polyfill for compact_blank method (introduced in Rails 6.1). Also refactored webpack asset handling to conditionally include React on Rails Pro files only when available, preventing NoMethodErrors in open-source installations. PR 2058 by justin808.

  • Duplicate Rake Task Execution: Fixed rake tasks executing twice during asset precompilation and other rake operations. Rails Engine was loading task files twice: once via explicit load calls in the rake_tasks block (Railtie layer) and once via automatic file loading from lib/tasks/ (Engine layer). This caused react_on_rails:assets:webpack, react_on_rails:generate_packs, and react_on_rails:locale tasks to run twice, significantly increasing build times. Removed explicit load calls and now rely on Rails Engine's standard auto-loading behavior. PR 2052 by justin808.

  • [Pro] Thread-Safe Connection Management: Fixed race conditions in ReactOnRailsPro::Request using double-checked locking. PR 2259 by AbanoubGhadban.

  • [Pro] JSON Parse Race Condition in Immediate Hydration: Fixed race condition where immediate_hydration could parse incomplete JSON during HTML streaming. Uses nextSibling check to verify props script completion. PR 2290 by AbanoubGhadban.

  • [Pro] Legacy Module Resolver Compatibility: Added main field to Pro package.json files for legacy module resolvers. PR 2256 by ihabadham.

  • [Pro] Client Disconnect Handling for Streaming: Catches IOError/Errno::EPIPE on disconnect, stops barrier to cancel producer tasks. PR 2137 by justin808.

  • [Pro] Node Renderer Worker Restart: Fixed "descriptor closed" error during restarts. Workers now perform graceful shutdowns with configurable gracefulWorkerRestartTimeout. PR 1970 by AbanoubGhadban.

  • [Pro] Body Duplication Bug On Streaming: Fixed bug when node renderer connection closed after partial streaming. PR 1995 by AbanoubGhadban.

  • [Pro] Fixed compatibility with httpx 1.6.x by requiring http-2 >= 1.1.1. PR 2141 by AbanoubGhadban.

  • [Pro] Fixed unnecessary bundle requests when RSC is disabled. PR 545 by AbanoubGhadban.

  • [Pro] Made default bundle paths consistent between node-renderer and Rails. PR 399 by alexeyr-ci.

Security

  • Development Dependencies Security: Addressed 58 Dependabot vulnerabilities in dev/test dependencies including critical issues in webpack (DOM clobbering XSS), nokogiri (libxml2 CVEs), activestorage, rack (5 DoS vulnerabilities), and jws (HMAC signature bypass). These changes only affect development environments—production gem code is unchanged. PR 2261 by ihabadham.

  • Command Injection Protection: Added security hardening to prevent potential command injection in package manager commands. PR #1881 by AbanoubGhadban.

  • [Pro] CVE-2025-55182 - React Server Components RCE: Updated react-on-rails-rsc peer dependency to v19.0.3. PR 2175 by AbanoubGhadban.

  • [Pro] CVE-2025-55183, CVE-2025-55184, CVE-2025-67779: Upgraded React to v19.0.3 and react-on-rails-rsc to v19.0.4 fixing source code exposure and denial of service vulnerabilities. PR 2233 by AbanoubGhadban.

Deprecated

  • [Pro] Node Renderer bundlePath: Renamed to serverBundleCachePath. Old option continues to work with deprecation warning. PR 2008 by justin808.

Documentation

  • Simplified Configuration Files: Improved configuration documentation and generator template for better clarity and usability. Reduced generator template from 67 to 42 lines (37% reduction). Added comprehensive testing configuration guide. Reorganized configuration docs into Essential vs Advanced sections. Enhanced Doctor program with diagnostics for server rendering and test compilation consistency. PR #2011 by justin808.

Developer (Contributors Only)

  • Monorepo Structure Reorganization: Restructured the monorepo to use two top-level product directories (react_on_rails/ and react_on_rails_pro/) instead of mixing source files at the root level. This improves organization and clarity for contributors working on either the open-source or Pro versions. Important for contributors: If you have an existing clone of the repository, you may need to update your IDE exclusion patterns and paths. See the updated CLAUDE.md for current project structure. PR 2114 by justin808.

  • Package Manager Migration to pnpm: Migrated the monorepo from Yarn Classic to pnpm for improved dependency management and faster installs. Contributors should reinstall dependencies with pnpm install after pulling this change. PR 2121 by justin808.

  • Bundle Size CI Monitoring: Added automated bundle size tracking to CI using size-limit. Compares PR bundle sizes against the base branch and fails if any package increases by more than 0.5KB. Includes local comparison tool (bin/compare-bundle-sizes) and bypass mechanism (bin/skip-bundle-size-check) for intentional size increases. PR 2149 by AbanoubGhadban.

  • Download Time CI Monitoring: Added automated download time tracking to CI using size-limit. Compares PR client import download times against the base branch and fails if any import increases by more than 10%. PR 2160 by AbanoubGhadban.

16.1.1 - 2025-09-24

Bug Fixes

  • React Server Components: Fixed bug in resolving react-server-client-manifest.json file path. The manifest file path is now correctly resolved using bundle_js_file_path for improved configuration flexibility and consistency in bundle management. PR 1818 by AbanoubGhadban

16.1.0 - 2025-09-23

New Features

  • Server Bundle Security: Added new configuration options for enhanced server bundle security and organization:

    • server_bundle_output_path: Configurable directory (relative to the Rails root) for server bundle output (default: "ssr-generated"). If set to nil, the server bundle will be loaded from the same public directory as client bundles. PR 1798 by justin808
    • enforce_private_server_bundles: When enabled, ensures server bundles are only loaded from private directories outside the public folder (default: false for backward compatibility) PR 1798 by justin808
  • Improved Bundle Path Resolution: Bundle path resolution for server bundles now works as follows:

    • If server_bundle_output_path is set, the server bundle is loaded from that directory.
    • If server_bundle_output_path is not set, the server bundle falls back to the client bundle directory (typically the public output path).
    • If enforce_private_server_bundles is enabled:
      • The server bundle will only be loaded from the private directory specified by server_bundle_output_path.
      • If the bundle is not found there, it will not fall back to the public directory.
    • If enforce_private_server_bundles is not enabled and the bundle is not found in the private directory, it will fall back to the public directory.
    • This logic ensures that, when strict enforcement is enabled, server bundles are never loaded from public directories, improving security and clarity of bundle resolution. PR 1798 by justin808
  • react_on_rails:doctor rake task: New diagnostic command to validate React on Rails setup and identify configuration issues. Provides comprehensive checks for environment prerequisites, dependencies, Rails integration, and Webpack configuration. Use rake react_on_rails:doctor to diagnose your setup, with optional VERBOSE=true for detailed output. PR 1791 by AbanoubGhadban

Deprecations

  • Deprecated generated_assets_dirs configuration: The legacy config.generated_assets_dirs option is now deprecated and will show a deprecation warning if used. Since Shakapacker is now required, asset paths are automatically determined from shakapacker.yml configuration. Remove any config.generated_assets_dirs from your config/initializers/react_on_rails.rb file. Use public_output_path in config/shakapacker.yml to customize asset output location instead. PR 1798 by justin808

API Improvements

  • Method Naming Clarification: Added public_bundles_full_path method to clarify bundle path handling:
    • public_bundles_full_path: New method specifically for webpack bundles in public directories
    • generated_assets_full_path: Now deprecated (backwards-compatible alias)
    • This eliminates confusion between webpack bundles and general Rails public assets PR 1798 by justin808

Security Enhancements

  • Private Server Bundle Enforcement: When enforce_private_server_bundles is enabled, server bundles bypass public directory fallbacks and are only loaded from designated private locations PR 1798 by justin808
  • Path Validation: Added validation to ensure server_bundle_output_path points to private directories when enforcement is enabled PR 1798 by justin808
  • Fixed command injection vulnerabilities: Replaced unsafe string interpolation in generator package installation commands with secure array-based system calls PR 1786 by justin808
  • Improved input validation: Enhanced package manager validation and argument sanitization across all generators PR 1786 by justin808
  • Hardened DOM selectors: Using CSS.escape() and proper JavaScript escaping for XSS protection PR 1791 by AbanoubGhadban

Added

  • [Pro] Core/Pro separation: Moved Pro features into dedicated lib/react_on_rails/pro/ and node_package/src/pro/ directories with clear licensing boundaries (now separated into packages/react-on-rails-pro/ package) PR 1791 by AbanoubGhadban
  • [Pro] Runtime license validation: Implemented Pro license gating with graceful fallback to core functionality when Pro license unavailable PR 1791 by AbanoubGhadban
  • [Pro] Enhanced immediate hydration: Improved immediate hydration functionality with Pro license validation and warning badges PR 1791 by AbanoubGhadban
  • [Pro] License documentation: Added NOTICE files in Pro directories referencing canonical REACT-ON-RAILS-PRO-LICENSE.md PR 1791 by AbanoubGhadban

Generator Improvements

  • Modern TypeScript patterns: Generators now produce more idiomatic TypeScript code with improved type inference instead of explicit type annotations PR 1786 by justin808
  • Optimized tsconfig.json: Updated compiler options to use "moduleResolution": "bundler" for better bundler compatibility PR 1786 by justin808
  • Enhanced Redux TypeScript integration: Improved type safety and modern React patterns (useMemo, type-only imports) PR 1786 by justin808
  • Smart bin/dev defaults: Generated bin/dev script now automatically navigates to /hello_world route for immediate component visibility PR 1786 by justin808
  • Better component templates: Removed unnecessary type annotations while maintaining type safety through TypeScript's inference PR 1786 by justin808
  • Cleaner generated code: Streamlined templates following modern React and TypeScript best practices PR 1786 by justin808
  • Improved helper methods: Added reusable component_extension helper for consistent file extension handling PR 1786 by justin808

Bug Fixes

  • Doctor rake task: Fixed LoadError in rake react_on_rails:doctor when using packaged gem. The task was trying to require excluded rakelib/task_helpers file. PR 1795 by justin808
  • Packs generator: Fixed error when server_bundle_js_file configuration is empty (default). Added safety check to prevent attempting operations on invalid file paths when server-side rendering is not configured. PR 1802 by justin808
  • Non-Packer Environment Compatibility: Fixed potential NoMethodError when using bundle path resolution in environments without Shakapacker PR 1798 by justin808
  • Shakapacker version requirements: Fixed inconsistent version requirements between basic pack generation (6.5.1+) and advanced auto-bundling features (7.0.0+). Added backward compatibility for users on Shakapacker 6.5.1-6.9.x while providing clear upgrade guidance for advanced features. Added new constants MINIMUM_SHAKAPACKER_VERSION_FOR_AUTO_BUNDLING and improved version checking performance with caching. PR 1798 by justin808

Code Improvements

  • PackerUtils abstraction removal: Removed unnecessary PackerUtils.packer abstraction method and replaced all calls with direct ::Shakapacker usage. This simplifies the codebase by eliminating an abstraction layer that was originally created to support multiple webpack tools but is no longer needed since we only support Shakapacker. All tests updated accordingly. PR 1798 by claude-code
  • Architecture refactoring: Centralized Pro utilities and clean separation between core and Pro helper functionality PR 1791 by AbanoubGhadban

16.0.0 - 2025-09-16

React on Rails v16 is a major release that modernizes the library with ESM support, removes legacy Webpacker compatibility, and introduces significant performance improvements. This release builds on the foundation of v14 with enhanced RSC (React Server Components) support and streamlined configuration.

See Release Notes for complete migration guide.

Major Enhancements

🚀 React Server Components (RSC) -- Requires React on Rails Pro

  • Enhanced RSC rendering flow: Eliminated double rendering and reduced HTTP requests
  • RSCRoute component: Seamless server-side rendering with automatic payload injection and hydration PR 1696 by AbanoubGhadban
  • Optimized RSC payload injection: Now injected after component HTML markup for better performance PR 1738 by AbanoubGhadban
  • Communication protocol v2.0.0: Supports uploading multiple bundles at once for improved efficiency

⚡ Performance & Loading Strategy

  • New generated_component_packs_loading_strategy: Choose from sync, async, or defer strategies PR 1712 by AbanoubGhadban
  • Async render function support: Components can now return from async render functions PR 1720 by AbanoubGhadban
  • Optimized client imports: Generated packs now import from react-on-rails/client for better tree-shaking PR 1706 by alexeyr-ci

Developer Experience

  • Enhanced error messaging: Clearer troubleshooting steps and prominent optimization warnings
  • Modern global access: Using globalThis instead of window/global detection PR 1727 by alexeyr-ci2
  • Simplified CI configuration: Clear minimum/latest dependency naming instead of oldest/newest
  • ReactRefreshWebpackPlugin v0.6.0 support: Added conditional logic for proper configuration PR 1748 by judahmeek
  • Version validation improvements: Fixed invalid warnings with pre-release versions PR 1742 by alexeyr-ci2

Breaking Changes

🔧 Webpacker Support Removed

  • Complete removal of Webpacker support. Shakapacker >= 6.0 is now required.
  • Migration:
    • Remove webpacker gem from your Gemfile
    • Install shakapacker gem version 6.0+ (8.0+ recommended)
    • Replace bin/webpacker commands with bin/shakapacker
    • Update webpacker configuration files to shakapacker equivalents
  • Removed files: rakelib/webpacker_examples.rake, lib/generators/react_on_rails/adapt_for_older_shakapacker_generator.rb

📦 Package System Modernization

  • ESM-only package: CommonJS require() no longer supported
  • Migration:
    • Replace require('react-on-rails') with import ReactOnRails from 'react-on-rails'
    • For Node.js < 20.19.0, upgrade or use dynamic imports
    • For TypeScript errors, upgrade to TypeScript 5.8+ and set module: "nodenext"

⚡ Configuration API Changes

  • defer_generated_component_packs deprecated → use generated_component_packs_loading_strategy

  • Migration:

    • defer_generated_component_packs: truegenerated_component_packs_loading_strategy: :defer
    • defer_generated_component_packs: falsegenerated_component_packs_loading_strategy: :sync
    • Recommended: generated_component_packs_loading_strategy: :async for best performance
  • force_load renamed to immediate_hydration for API clarity

  • Migration:

    • config.force_load = trueconfig.immediate_hydration = true
    • react_component(force_load: true)react_component(immediate_hydration: true)
    • redux_store(force_load: true)redux_store(immediate_hydration: true)
  • Note: immediate_hydration requires React on Rails Pro license

🔄 Async API Changes

  • ReactOnRails.reactOnRailsPageLoaded() is now async
  • Migration: Add await when calling: await ReactOnRails.reactOnRailsPageLoaded()

🏗️ Runtime Suggested Versions

  • Ruby: 3.2 - 3.4 (was 3.0 - 3.3)
  • Node.js: 20 - 22 (was 16 - 20)
  • Note: These are CI-tested versions; older versions may work but aren't guaranteed

🎯 Generator Improvements

  • Install generator now validates JavaScript package manager presence
  • Improved error handling with Thor::Error instead of exit(1)
  • Enhanced error messages with clearer troubleshooting steps

[15.0.0] - 2025-08-28 - RETRACTED

⚠️ This version has been retracted due to API design issues. Please upgrade directly to v16.0.0.

The force_load feature was incorrectly available without a Pro license and has been renamed to immediate_hydration for better clarity. All features from v15 are available in v16 with the corrected API.

14.2.0 - 2025-03-03

Added

  • Add export option 'react-on-rails/client' to avoid shipping server-rendering code to browsers (~5KB improvement) PR 1697 by Romex91.

Fixed

  • Fix obscure errors by introducing FULL_TEXT_ERRORS PR 1695 by Romex91.
  • Disable esModuleInterop to increase interoperability PR 1699 by alexeyr-ci.
  • Resolved 14.1.1 incompatibility with eslint & made sure that spec/dummy is linted by eslint. PR 1693 by judahmeek.

Changed

14.1.1 - 2025-01-15

Fixed

  • Separated streamServerRenderedReactComponent from the ReactOnRails object in order to stop users from getting errors during Webpack compilation about needing the stream-browserify package. PR 1680 by judahmeek.
  • Removed obsolete js-yaml peer dependency. PR 1678 by alexeyr-ci.

14.1.0 - 2025-01-06

Fixed

  • Incorrect type and confusing name for ReactOnRails.registerStore, use registerStoreGenerators instead. PR 1651 by alexeyr-ci.
  • Changed the ReactOnRails' version checker to use ReactOnRails.configuration.node_modules_location to determine the location of the package.json that the react-on-rails dependency is expected to be set by.
  • Also, all errors that would be raised by the version checking have been converted to Rails.Logger warnings to avoid any breaking changes. PR 1657 by judahmeek.
  • Enable use as a git: dependency. PR 1664 by alexeyr-ci.

Added

  • Added streaming server rendering support:
    • PR #1633 by AbanoubGhadban.
      • New stream_react_component helper for adding streamed components to views
      • New streamServerRenderedReactComponent function in the react-on-rails package that uses React 18's renderToPipeableStream API
      • Enables progressive page loading and improved performance for server-rendered React components
    • Added support for replaying console logs that occur during server rendering of streamed React components. This enables debugging of server-side rendering issues by capturing and displaying console output on the client and on the server output. PR #1647 by AbanoubGhadban.
    • Added support for handling errors happening during server rendering of streamed React components. It handles errors that happen during the initial render and errors that happen inside suspense boundaries. PR #1648 by AbanoubGhadban.
    • Added support for passing options to YAML.safe_load when loading locale files with config.i18n_yml_safe_load_options. PR #1668 by dzirtusss.

Changed

  • Console replay script generation now awaits the render request promise before generating, allowing it to capture console logs from asynchronous operations. This requires using a version of the Node renderer that supports replaying async console logs. PR #1649 by AbanoubGhadban.

14.0.5 - 2024-08-20

Fixed

14.0.4 - 2024-07-02

Improved

  • Improved dependency management by integrating package_json. PR 1639 by vaukalak.

Changed

  • Update outdated GitHub Actions to use Node.js 20.0 versions instead PR 1623 by adriangohjw.

14.0.3 - 2024-06-28

Fixed

14.0.2 - 2024-06-11

Fixed

14.0.1 - 2024-05-16

Fixed

  • Pack Generation: Added functionality that will add an import statement, if missing, to the server bundle entry point even if the auto-bundle generated files still exist PR 1610 by judahmeek.

14.0.0 - 2024-04-03

Major bump because dropping support for Ruby 2.7 and deprecated webpackConfigLoader.js.

Removed

Fixed

  • Trimmed the Gem to remove package.json which could cause superflous security warnings. PR 1605 by justin808.
  • Prevent displaying the deprecation message for using webpacker_precompile? method and webpacker:clean rake task when using Shakapacker v7+ PR 1592 by ahangarha.
  • Fixed Typescript types for ServerRenderResult, ReactComponent, RenderFunction, and RailsContext interfaces. PR 1582 & PR 1585 by kotarella1110
  • Removed a workaround in JsonOutput#escape for an no-longer supported Rails version. Additionally, removed Utils.rails_version_less_than_4_1_1
    which was only used in the workaround. PR 1580 by wwahammy

Added

13.4.0 - 2023-07-30

Fixed

  • Fixed Pack Generation logic during assets:precompile if auto_load_bundle is false & components_subdirectory is not set. PR 1567 by blackjack26 & judahmeek.

Improved

  • Improved performance by removing an unnecessary JS eval from Ruby. PR 1544 by wyattades.

Added

Changed

  • Throw error when attempting to redefine ReactOnRails. PR 1562 by rubenochiavone.
  • Prevent generating FS-based packs when component_subdirectory configuration is not present. PR 1567 by blackjack26.
  • Removed a requirement for autoloaded pack files to be generated as part of CI or deployment separate from initial Shakapacker bundling. PR 1545 by judahmeek.

13.3.5 - 2023-05-31

Fixed

  • Fixed race condition where a React component could attempt to initialize before it had been registered. PR 1540 by judahmeek.

13.3.4 - 2023-05-23

Added

  • Improved functionality of Filesystem-based pack generation & auto-bundling. Added make_generated_server_bundle_the_entrypoint configuration key. PR 1531 by judahmeek.

Removed

  • Removed unneeded HMR=true from Procfile.dev in install template PR 1537 by ahangarha.

13.3.3 - 2023-03-21

Fixed

13.3.2 - 2023-02-24

Fixed

  • Fixed the bug in bin/dev and bin/dev-static scripts by using system instead of exec and remove option to pass arguments PR 1519 by ahangarha.

13.3.1 - 2023-01-30

Added

  • Optimized ReactOnRails::TestHelper's RSpec integration using when_first_matching_example_defined. PR 1496 by mcls.

Fixed

13.3.0 - 2023-01-29

Fixed

  • Fixed pack not found warning while using react_component and react_component_hash helpers, even when corresponding chunks are present. PR 1511 by pulkitkkr.
  • Fixed FS-based packs generation functionality to trigger pack generation on the creation of a new React component inside components_subdirectory. PR 1506 by pulkitkkr.
  • Upgrade several JS dependencies to fix security issues. PR 1514 by ahangarha.

Added

  • Added ./bin/dev and ./bin/dev-static executables to ease and standardize running the dev server. PR 1491 by ahangarha.

13.2.0 - 2022-12-23

Fixed

  • Fix reactOnRailsPageUnloaded when there is no component on the page. Important for apps using both hotwire and react_on_rails. PR 1498 by NhanHo.
  • Fixing wrong type. The throwIfMissing param of getStore should be optional as it defaults to true. PR 1480 by wouldntsavezion.

Added

13.1.0 - 2022-08-20

Improved

  • Removed addition of mini_racer gem by default. PR 1453 by vtamara and tomdracz.

    Using mini_racer makes most sense when deploying or building in environments that do not have Javascript runtime present. Since react_on_rails requires Node.js, there's no reason to override ExecJS runtime with mini_racer.

    To migrate this change, remove mini_racer gem from your Gemfile and test your app for correct behaviour. You can continue using mini_racer and it will be still picked as the default ExecJS runtime, if present in your app Gemfile.

  • Upgraded the example test app in spec/dummy to React 18. PR 1463 by alexeyr.

  • Added file-system-based automatic bundle generation feature. PR 1455 by pulkitkkr.

Fixed

  • Correctly unmount roots under React 18. PR 1466 by alexeyr.

  • Fixed the You are importing hydrateRoot from "react-dom" [...] You should instead import it from "react-dom/client" warning under React 18 (#1441). PR 1460 by alexeyr.

    In exchange, you may see a warning like this when building using any version of React below 18:

    WARNING in ./node_modules/react-on-rails/node_package/lib/reactHydrateOrRender.js19:25-52
    Module not found: Error: Can't resolve 'react-dom/client' in '/home/runner/work/react_on_rails/react_on_rails/spec/dummy/node_modules/react-on-rails/node_package/lib'
     @ ./node_modules/react-on-rails/node_package/lib/ReactOnRails.js 34:45-78
     @ ./client/app/packs/client-bundle.js 5:0-42 32:0-23 35:0-21 59:0-26
    

    Note: The node_package/lib/ path in these error examples is now packages/react-on-rails/lib/ in the current structure.

    It can be safely suppressed in your Webpack configuration.

13.0.2 - 2022-03-09

Fixed

  • React 16 doesn't support version property, causing problems loading React on Rails. PR 1435 by justin808.

13.0.1 - 2022-02-09

Improved

13.0.0 - 2022-02-08

Breaking

  • Removed webpacker as a dependency. Add gem Shakapacker to your project, and update your package.json to also use shakapacker.

Fixed

  • Proper throwing of exceptions.
  • Default configuration better handles test env.

12.6.0 - 2022-01-22

Added

  • A rendering_props_extension configuration which takes a module with an adjust_props_for_client_side_hydration method, which is used to process props differently for server/client if prerender is set to true. PR 1413 by gscarv13 & judahmeek.

12.5.2 - 2021-12-29

Fixed

  • Usage of config.build_production_command for custom command for production builds fixed. PR 1415 by judahmeek.

12.5.1 - 2021-12-27

Fixed

  • A fatal server rendering error if running an ReactOnRails >=12.4.0 with ReactOnRails Pro <2.4.0. PR 1412 by judahmeek.

12.5.0 - 2021-12-26

Added

  • Support for React 18, including the changed SSR API. PR 1409 by kylemellander.
  • Added Webpack configuration files as part of the generator and updated webpacker to version 6. PR 1404 by gscarv13.
  • Supports Rails 7.

Changed

  • Changed logic of determining the usage of the default rails/webpacker Webpack config or a custom command to only check if the config.build_production_command is defined. PR 1402 by justin808 and gscarv13.
  • Minimum required Ruby is 2.7 to match latest rails/webpacker.

12.4.0 - 2021-09-22

Added

  • ScoutAPM tracing support for server rendering PR 1379 by justin808.

  • Ability to stop React on Rails from modifying or creating the assets:precompile task. PR 1371 by justin808. Thanks to elstgav for the suggestion!

  • Added the ability to have render functions return a promise to be awaited by React on Rails Pro Node Renderer. PR 1380 by judahmeek

12.3.0 - 2021-07-26

Added

  • Ability to use with Turbo (@hotwired/turbo), as Turbolinks gets obsolete. PR 1374 by pgruener and PR 1377 by mdesantis.

    To configure turbo the following option can be set:
    ReactOnRails.setOptions({ turbo: true })

12.2.0 - 2021-03-25

Added

  • Ability to configure server React rendering to throw rather than just logging the error. Useful for
    React on Rails Pro Node rendering PR 1365 by justin808.

12.1.0 - 2021-03-23

Added

Fixed

12.0.4 - 2020-11-14

Fixed

12.0.3 - 2020-09-20

Fixed

12.0.2 - 2020-07-09

Fixed

12.0.1 - 2020-07-09

Fixed

  • Changed invocation of webpacker:clean to use a very large number of versions so it does not accidentally delete the server-bundle.js. PR 1306 by By justin808.

12.0.0 - 2020-07-08

For upgrade instructions, see the upgrading guide.

Major Improvements

  1. React Hooks Support for top level components
  2. Typescript bindings
  3. rails/webpacker "just works" with React on Rails by default.
  4. i18n support for generating a JSON file rather than a JS file.

BREAKING CHANGE

In order to solve the issues regarding React Hooks compatibility, the number of parameters
for functions is used to determine if you have a generator function that will get invoked to
return a React component, or you are registering a functional React component. Alternately, you can
set JavaScript property renderFunction on the function for which you want to return to be
invoked to return the React component. In that case, you won't need to pass any unused params.
PR 1268 by justin808

See docs/guides/upgrading-react-on-rails
for details.

Other Updates

  • react_on_rails fully supports rails/webpacker. The example test app in spec/dummy was recently converted over to use rails/webpacker v4+. It's a good example of how to leverage rails/webpacker's Webpack configuration for server-side rendering.

  • Changed the precompile task to use the rails/webpacker one by default

  • Updated generators to use React hooks

  • Requires the use of rails/webpacker view helpers

  • If the webpacker Webpack config files exist, then React on Rails will not override the default
    assets:precompile set up by rails/webpacker. If you are not using the rails/webpacker setup for Webpack,
    then be sure to remove the JS files inside of config/webpack, like config/webpack/production.js.

  • Removed env_javascript_include_tag and env_stylesheet_link_tag as these are replaced by view helpers
    from rails/webpacker

  • Removal of support for old Rubies and Rails.

  • Removal of config.symlink_non_digested_assets_regex as it's no longer needed with rails/webpacker.
    If any business needs this, we can move the code to a separate gem.

  • Added configuration option same_bundle_for_client_and_server with default false because

    1. Production applications would typically have a server bundle that differs from the client bundle
    2. This change only affects trying to use HMR with react_on_rails with rails/webpacker.

    The previous behavior was to always go to the webpack-dev-server for the server bundle if the
    webpack-dev-server was running and the server bundle was found in the manifest.json.

    If you are using the same bundle for client and server rendering, then set this configuration option
    to true. By justin808.

  • Added support to export locales in JSON format. New option added i18n_output_format which allows to
    specify locales format either JSON or JS. JSON format is now the default.

    Use this config setting to get the old behavior: config.i18n_output_format = 'js'

    PR 1271 by ashgaliyev.

  • Added Typescript definitions to the Node package. By justin808 and judahmeek in PR 1287.

  • Removed restriction to keep the server bundle in the same directory with the client bundles. Rails/webpacker 4 has an advanced cleanup that will remove any files in the directory of other Webpack files. Removing this restriction allows the server bundle to be created in a sibling directory. By justin808.

11.3.0 - 2019-05-24

Added

  • Added method for retrieving any option from render_options PR 1213
    by ashgaliyev.

  • html_options has an option for 'tag' to set the html tag name like this: html_options: { tag: "span" }.
    PR 1208 by tahsin352.

11.2.2 - 2018-12-24

Improved

  • rails_context can more easily be called from controller methods. The mandatory param of server_side has been made optional.

11.2.1 - 2018-12-06

MIGRATION for v11.2

  • If using React on Rails Pro, upgrade react_on_rails_pro to a version >= 1.3.

Improved

  • To support React v16, updated API for manually calling ReactOnRails.render(name, props, domNodeId, hydrate). Added 3rd @param hydrate Pass truthy to update server rendered html. Default is falsey Any truthy values calls hydrate rather than render. PR 1159 by justin808 and coopersamuel.

  • Enabled the use of webpack-dev-server with Server-side rendering. PR 1173 by justin808 and judahmeek.

Changed

  • Changed the default for:

    config.raise_on_prerender_error = Rails.env.development?

    Thus, developers will need to fix server rendering errors before continuing.
    PR 1145 by justin808.

11.2.0 - 2018-12-06

Do not use. Unpublished. Caused by an issue with the release script.

11.1.8 - 2018-10-14

Improved

  • Improved tutorial and support for HMR when using rails/webpacker for Webpack configuration. PR 1156 by justin808.

11.1.7 - 2018-10-10

Fixed

  • Fixed bug where intl parsing would fail when trying to parse integers or blank entries. by sepehr500

11.1.6 - 2018-10-05

Fixed

  • Fix client startup invoking render prematurely, AGAIN. Fix additional cases of client startup failing during interactive readyState". Closes issue #1150. PR 1152 by rakelley.

11.1.5 - 2018-10-03

Fixed

11.1.4 - 2018-09-12

Fixed

11.1.3 - 2018-08-26

Fixed

11.1.2 - 2018-08-18

Fixed

  • Tests now properly exit if the config.build_test_command fails!
  • Source path for project using Webpacker would default to "app/javascript" even if when the node_modules
    directory was set to "client". Fix now makes the configuration of this crystal clear.
  • renamed method RenderOptions.has_random_dom_id? to RenderOptions.random_dom_id? for rubocop rule.
    PR 1133 by justin808

11.1.1 - 2018-08-09

Fixed

11.1.0 - 2018-08-07

Added

  • Add random dom id option. This new global and react_component helper option allows configuring whether or not React on Rails will automatically add a random id to the DOM node ID. PR 1121 by justin808
    • Added configuration option random_dom_id
    • Added method RenderOptions has_random_dom_id?

Fixed

11.0.10 - 2018-07-22

Fixed

  • Much better logging of rendering errors when there are lots of props. Only the a 1,000 chars are logged, and the center is indicated to be truncated. PR 1117 and PR 1118 by justin808.
  • Properly clearing hydrated stores when server rendering. PR 1120 by squadette.

11.0.9 - 2018-06-24

11.0.8 - 2018-06-15

Fixed

  • HashWithIndifferent access for props threw if used for props. PR 1100 by justin808.
  • Test helper for detecting stale bundles did not properly handle the case of a server-bundle.js without a hash.PR 1102 by justin808.
  • Fix test helper determination of stale assets. PR 1093 by justin808.

Changed

  • Document how to manually rehydrate XHR-substituted components on client side. PR 1095 by hchevalier.

11.0.7 - 2018-05-16

Fixed

11.0.6 - 2018-05-15

Changed

  • Even more detailed errors for Honeybadger and Sentry when there's a JSON parse error on server rendering. PR 1086 by justin808.

11.0.5 - 2018-05-11

Changed

11.0.4 - 2018-05-3

Changed

  • Throw if configuration.generated_assets_dir specified, and using webpacker, and if that doesn't match the public_output_path. Otherwise, warn if generated_assets_dir is specified
  • Fix the setup for tests for spec/dummy so they automatically rebuild by correctly setting the source_path in the webpacker.yml
  • Updated documentation for the testing setup.
  • Above in PR 1072 by justin808.
  • react_component_hash has implicit prerender: true because it makes no sense to have react_component_hash not use prerrender. Improved docs on react_component_hash. Also, fixed issue where checking gem existence. PR 1077 by justin808.

11.0.3 - 2018-04-24

Fixed

  • Fixed issue with component script initialization when using react_component_hash. PR 1071 by jblasco3.

11.0.2 - 2018-04-24

Fixed

11.0.1 - 2018-04-23

Added

  • react_component allows logging_on_server specified at the component level. PR 1068 by justin808.

Fixed

11.0.0 - 2018-04-21

MIGRATION for v11

  • Unused server_render_method was removed from the configuration. If you want to use a custom renderer, contact justin@shakacode.com. We have a custom node rendering solution in production for egghead.io.
  • Removed ReactOnRails::Utils.server_bundle_file_name and ReactOnRails::Utils.bundle_file_name. These are part of the performance features of "React on Rails Pro".
  • Removed ENV["TRACE_REACT_ON_RAILS"] usage and replacing it with config.trace.

Enhancements: Better Error Messages, Support for React on Rails Pro

  • Tracing (debugging) options are simplified with a single config.trace setting that defaults to true for development and false otherwise.
  • Calls to setTimeout, setInterval, clearTimeout will now always log some message if config.trace is true. Your JavaScript code should not be calling setTimout when server rendering.
  • Errors raised are of type ReactOnRailsError, so you can see they came from React on Rails for debugging.
  • Removed ReactOnRails::Utils.server_bundle_file_name and ReactOnRails::Utils.bundle_file_name.
  • No longer logging the railsContext when server logging.
  • Rails.env is provided in the default railsContext, as suggested in issue #697.
    PR 1065 by justin808.

Fixes

  • More exact version checking. We keep the react_on_rails gem and the react-on-rails node package at
    the same exact versions so that we can be sure that the interaction between them is precise.
    This is so that if a bug is detected after some update, it's critical that
    both the gem and the node package get the updates. This change ensures that the package.json specification does not use a
    ~ or ^ as reported in issue #1062. PR 1063 by justin808.
  • Sprockets: Now use the most recent manifest when creating symlinks. See issue #1023. PR 1064 by justin808.

10.1.4 - 2018-04-11

Fixed

  • Changed i18n parsing to convert ruby i18n argument syntax into FormatJS argument syntax. PR 1046 by sepehr500.

  • Fixed an issue where the spec compiler check would fail if the project path contained spaces. PR 1045 by andrewmarkle.

  • Updated the default build_production_command that caused production assets to be built with development settings. PR 1053 by Roman Kushnir.

10.1.3 - 2018-02-28

Fixed

  • Improved error reporting on version mismatches between Javascript and Ruby packages. PR 1025 by theJoeBiz.

10.1.2 - 2018-02-27

Fixed

  • Use ReactDOM.hydrate() for hydrating a SSR component if available. ReactDOM.render() has been deprecated for use on SSR components in React 16 and this addresses the warning. PR 1028 by theJoeBiz.

10.1.1 - 2018-01-26

Fixed

10.1.0 - 2018-01-23

Added

  • Added 2 cache helpers: ReactOnRails::Utils.bundle_file_name(bundle_name) and ReactOnRails::Utils.server_bundle_file_name
    for easy access to the hashed filenames for use in cache keys. PR 1018 by justin808.

Fixed

  • Use Redux component in the generated Redux Hello World example: PR 1006 by lewaabahmad.
  • Fixed Utils.bundle_js_file_path generating the incorrect path for manifest.json in webpacker projects: Issue #1011 by elstgav

10.0.2 - 2017-11-10

Fixed

  • Remove unnecessary dependencies from released NPM package: PR 968 by tricknotes.

10.0.1 - 2017-10-28

Fixed

  • Fixed react_component_hash functionality in cases of prerendering errors: PR 960 by Judahmeek.
  • Fix to add missing dependency to run generator spec individually: PR 962 by tricknotes.
  • Fixes check for i18n_dir in LocalesToJs returning false when i18n_dir was set. PR 899 by hakongit.
  • Fixed mistake in rubocop comments that led to errors when handling exceptions in ReactOnRails::ServerRendering::Exec PR 963 by railsme.
  • Fixed and improved I18n directories checks: PR 967 by railsme

10.0.0 - 2017-10-08

Created

  • Created react_component_hash method for react_helmet support.

Deprecated

  • Deprecated react_component functionality for react_helmet support.
    To clarify, the method itself is not deprecated, only certain functionality which has been moved to react_component_hash
    PR 951 by Judahmeek.

9.0.3 - 2017-09-20

Improved

9.0.2 - 2017-09-10

Fixed

9.0.1 - 2017-09-10

Fixed

9.0.0 - 2017-09-06

Updated React on Rails to depend on rails/webpacker. PR 908 by justin808.

9.0 from 8.x. Upgrade Instructions

Moved to our documentation.

8.0.7 - 2017-08-16

Fixed

  • Fixes generator bug by keeping blank line at top in case existing .gitignore does not end in a newline. #916 by justin808.

8.0.6 - 2017-07-19

Fixed

  • Fixes server rendering when using a CDN. Server rendering would try to fetch a file with the "asset_host". This change updates the webpacker_lite dependency to 2.1.0 which has a new helper pack_path. #901 by justin808. Be sure to update webpacker_lite to 2.1.0.
  • The package.json file created by the generator now creates minified javascript production builds by default. This was done by adding the -p flag to Webpack on the build:production script. #895 by serodriguez68
  • Fixes GitUtils.uncommitted_changes? throwing an error when called in an environment without Git, and allows install generator to be run successfully with --ignore-warnings #878 by jasonblalock.

8.0.5 - 2017-07-04

Fixed

  • Corrects devBuild value for webpack production build from webpackConfigLoader. #877 by chenqingspring.
  • Remove contentBase deprecation warning message. #878 by ened .
  • Removes invalid reference to _railsContext in the generated files. #886 by justin808.
  • All tests run against Rails 5.1.2

Note: 8.0.4 skipped.

8.0.3 - 2017-06-19

Fixed

8.0.2 - 2017-06-04

Fixed

  • Any failure in webpack to build test files quits tests.
  • Fixed a Ruby 2.4 potential crash which could cause a crash due to pathname change in Ruby 2.4.
  • CI Improvements:
    • Switched to yarn link and removed relative path install of react-on-rails
    • Removed testing of Turbolinks 2
    • All tests run against Rails 5.1.1
    • Fixed test failures against Ruby 2.4
  • #862 by justin808

8.0.1 - 2017-05-30

Fixed

8.0.0 - 2017-05-29

  • Generators and full support for webpacker_lite
  • No breaking changes to move to 8.0.0 other than the default for this setting changed to nil. If you depended on the default of this setting and are using the asset pipeline (and not webpacker_lite), then add this to your config/initializers/react_on_rails.rb:
    symlink_non_digested_assets_regex: /\.(png|jpg|jpeg|gif|tiff|woff|ttf|eot|svg|map)/,
  • For an example of migration, see: react-webpack-rails-tutorial PR #395
  • For a simple example of the webpacker_lite setup, run the basic generator.

8.0.0-beta.3 - 2017-05-27

Changed

8.0.0-beta.2 - 2017-05-08

Changed

Removed unnecessary values in default paths.yml files for generators. #834 by justin808.

8.0.0-beta.1 - 2017-05-03

Added

Support for WebpackerLite in the generators. #822 by kaizencodes and justin808.

Changed

Breaking change is that the default value of symlink_non_digested_assets_regex has changed from this
old value to nil. This is a breaking change if you didn't have this value set in your
config/initializers/react_on_rails.rb file and you need this because you're using webpack's CSS
features and you have not switched to webpacker lite.

symlink_non_digested_assets_regex: /\.(png|jpg|jpeg|gif|tiff|woff|ttf|eot|svg|map)/,

7.0.4 - 2017-04-27

  • Return empty json when nil in json_safe_and_pretty #824 by dzirtusss

7.0.3 - 2017-04-27

Same as 7.0.1.

7.0.2 - 2017-04-27

Accidental release of beta gem here

7.0.1 - 2017-04-27

Fixed

  • Fix to handle nil values in json_safe_and_pretty #823 by dzirtusss

7.0.0 - 2017-04-25

Changed

  • Any version differences in gem and node package for React on Rails throw an error #821 by justin808

Fixed

  • Fixes serious performance regression when using String props for rendering. #821 by justin808

6.10.1 - 2017-04-23

Fixed

6.10.0 - 2017-04-13

Added

  • Add an ability to return multiple HTML strings in a Hash as a result of react_component method call. Allows to build <head> contents with React Helmet. #800 by udovenko.

Fixed

  • Fix PropTypes, createClass deprecation warnings for React 15.5.x. #804 by udovenko .

6.9.3 - 2017-04-03

Fixed

  • Removed call of to_json on strings when formatting props. #791 by justin808.

6.9.2 - 2017-04-02

Changed

  • Update version_checker.rb to logger.error rather than logger.warn for gem/npm version mismatch. #788 by justin808.

Fixed

  • Remove pretty formatting of JSON in development. #789 by justin808
  • Clear hydrated stores with each server rendered block. #785 by udovenko

6.9.1 - 2017-03-30

Fixed

  • Fixes Crash in Development for String Props. #784 by justin808.

6.9.0 - 2017-03-29

Fixed

  • Fixed error in the release script. #767 by isolo.

Changed

Added

  • Add option to specify i18n_yml_dir in order to include only subset of locale files when generating translations.js & default.js for react-intl.
    #777 by danijel.

6.8.2 - 2017-03-24

Fixed

  • Change webpack output path to absolute and update webpack to version ^2.3.1. #771 by cheremukhin23.

6.8.1 - 2017-03-21

Fixed

  • Fixed error "The node you're attempting to unmount was rendered by another copy of React." #706 when navigating to cached page using Turbolinks #763 by szyablitsky.

6.8.0 - 2017-03-06

Added

  • Converted to Webpack v2 for generators, tests, and all example code. #742 by justin808.

6.7.2 - 2017-03-05

Improved

  • Improve i18n Integration with a better error message if the value of the i18n directory is invalid. #748 by justin808.

6.7.1 - 2017-02-28

No changes other than a test fix.

6.7.0 - 2017-02-28

IMPORTANT

  • If you installed 6.6.0, you will need to comment out the line matching i18n_dir unless you are using this feature. 6.7.1 will give you an error like:
Errno::ENOENT: No such file or directory @ rb_sysopen - /tmp/build_1444a5bb9dd16ddb2561c7aff40f0fc7/my-app-816d31e9896edd90cecf1402acd002c724269333/client/app/libs/i18n/translations.js

Commenting out this line addresses the issue:

config.i18n_dir = Rails.root.join("client", "app", "libs", "i18n")

Added

  • Allow using rake task to generate javascript locale files. The test helper automatically creates the localization files when needed. #717 by JasonYCHuang.

Fixed

6.6.0 - 2017-02-18

Added

6.5.1 - 2017-02-11

Fixed

6.5.0 - 2017-01-31

Added

  • Allow generator function to return Object with property renderedHtml (already could return Object with props redirectLocation, error) rather than a React component or a function that returns a React component. One reason to use a generator function is that sometimes in server rendering, specifically with React Router v4, you need to return the result of calling ReactDOMServer.renderToString(element). #689 by justin808.

Fixed

6.4.2 - 2017-01-17

Fixed

  • Added OS detection for install generator, system call for Windows and unit-tests for it. #666 by GeorgeGorbanev.

6.4.1 - 2017-1-17

No changes.

6.4.0 - 2017-1-12

Possible Breaking Change

  • Since foreman is no longer a dependency of the React on Rails gem, please run gem install foreman. If you are using rvm, you may wish to run rvm @global do gem install foreman to install foreman for all your gemsets.

Fixed

  • Removed foreman as a dependency. #678 by x2es.

Added

  • Automatically generate i18n javascript files for react-intl when the serve starts up. #642 by JasonYCHuang.

6.3.5 - 2017-1-6

Fixed

  • The Redux generator now creates a HelloWorld component that uses redux rather than local state. #669 by justin808.

6.3.4 - 2016-12-25

Fixed
  • Disable Turbolinks support when not supported. #650 by ka2n.

6.3.3 - 2016-12-25

Fixed
  • By using the hook on turbolinks:before-visit to unmount the components, we can ensure that components are unmounted even when Turbolinks cache is disabled. Previously, we used turbolinks:before-cache event hook. #644 by volkanunsal.
  • Added support for Ruby 2.0 #651 by bbonamin.

6.3.2 - 2016-12-5

Fixed
  • The react_component method was raising a NameError when ReactOnRailsHelper was included in a plain object. #636 by jtibbertsma.
  • "Node parse error" for node server rendering. #641 by alleycat-at-git and rocLv
  • Better error handling when the react-on-rails node package entry is missing.#602 by benjiwheeler.

6.3.1 - 2016-11-30

Changed
  • Improved generator post-install help messages. #631 by justin808.

6.3.0 - 2016-11-30

Changed
  • Modified register API to allow registration of renderers, allowing a user to manually render their app to the DOM. This allows for code splitting and deferred loading. #581 by jtibbertsma.

  • Updated Basic Generator & Linters. Examples are simpler. #624 by Judahmeek.

  • Slight improvement to the 'no hydrated stores' error. #605 by cookiefission.

  • Don't assume ActionMailer is available. #608 by tuzz.

6.2.1 - 2016-11-19

  • Removed unnecessary passing of context in the HelloWorld Container example and basic generator. #612 by justin808

  • Turbolinks 5 bugfix to use before-cache, not before-render. #611 by volkanunsal.

6.2.0 - 2016-11-19

Changed
  • Updated the generator templates to reflect current best practices, especially for the Redux version. #584 by nostophilia.

6.1.2 - 2016-10-24

Fixed
  • Added compatibility with older manifest.yml files produced by Rails 3 Sprockets when symlinking digested assets during precompilation #566 by etripier.

6.1.1 - 2016-09-09

Fixed
  • React on Rails was incorrectly failing to create symlinks when a file existed in the location for the new symlink. #491 by robwise and justin808.

6.1.0 - 2016-08-21

Added
  • Node option for installer added as alternative for server rendering #469 by jbhatab.
  • Server rendering now supports contexts outside of browser rendering, such as ActionMailer templates #486 by eacaps.
  • Added authenticityToken() and authenticityHeaders() javascript helpers for easier use when working with CSRF protection tag generated by Rails #517 by dzirtusss.
  • Updated JavaScript error handling on the client side. Errors in client rendering now pass through to the browser #521 by dzirtusss.
Fixed
  • React on Rails now correctly parses single-digit version strings from package.json #491 by samphilipd .
  • Fixed assets symlinking to correctly use filenames with spaces. Beginning in #510, ending in #513 by dzirtusss.
  • Check encoding of request's original URL and force it to UTF-8 #527 by lucke84

6.0.5 - 2016-07-11

Added
  • Added better error messages to avoid issues with shared Redux stores #470 by justin808.

6.0.4 - 2016-06-13

Fixed
  • Added a polyfill for clearTimeout which is used by babel-polyfill #451 by martyphee

6.0.3 - 2016-06-07

Fixed

6.0.2 - 2016-06-06

Fixed
  • Fix collisions in ids of DOM nodes generated by react_component by indexing in using a UUID rather than an auto-increment value. This means that it should be overridden using the id parameter of react_component if one wants to generate a predictable id (e.g. for testing purpose). See Issue #437. Fixed in #438 by Michael Baudino.

6.0.1 - 2016-05-27

Fixed

6.0.0 - 2016-05-25

Breaking Changes
  • Added automatic compilation of assets at precompile is now done by ReactOnRails. Thus, you don't need to provide your own assets.rake file that does the precompilation.
    #398 by robwise, jbhatab, and justin808.

  • Migration to v6

    • Do not run the generator again if you've already run it.

    • See shakacode/react-webpack-rails-tutorial/pull/287 for an example of upgrading from v5.

    • To configure the asset compilation you can either

      1. Specify a config/react_on_rails setting for build_production_command to be nil to turn this feature off.
      2. Specify the script command you want to run to build your production assets, and remove your assets.rake file.
    • If you are using the ReactOnRails test helper, then you will need to add the 'config.npm_build_test_command' to your config to tell react_on_rails what command to run when you run rspec.

  • See shakacode/react-webpack-rails-tutorial #287 for an upgrade example. The PR has a few comments on the upgrade.

Here is the addition to the generated config file:

  # This configures the script to run to build the production assets by webpack. Set this to nil
  # if you don't want react_on_rails building this file for you.
  config.build_production_command = "npm run build:production"

  # If you are using the ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
  # with rspec then this controls what npm command is run
  # to automatically refresh your webpack assets on every test run.
  config.npm_build_test_command = "npm run build:test"
Fixed
  • Fixed errors when server rendered props contain \u2028 or \u2029 characters #375 by mariusandra
  • Fixed "too early unmount" which caused problems with Turbolinks 5 not updating the screen #425 by szyablitsky
Added
  • Experimental ability to use node.js process for server rendering. See #380 by alleycat-at-git.
  • Non-digested version of assets in public folder #413 by alleycat-at-git.
  • Cache client/node_modules directory to prevent Heroku from reinstalling all modules from scratch #324 by modosc.
  • ReactOnRails.reactOnRailsPageLoaded() is exposed in case one needs to call this manually and information on async script loading added. See #315 by SqueezedLight.
Changed
  • #398 by robwise, jbhatab, and justin808 contains:
    • Only one webpack config is generated for server and client config. Package.json files were changed to reflect this.
    • Added npm_build_test_command to allow developers to change what npm command is automatically run from rspec.
  • Replace URI with Addressable gem. See #405 by lucke84
Removed
  • #398 by robwise, jbhatab, and justin808 contains:
    • Server rendering is no longer an option in the generator and is always accessible.
    • Removed lodash, jquery, and loggerMiddleware from the generated code.
    • Removed webpack watch check for test helper automatic compilation.

5.2.0 - 2016-04-08

Added
  • Support for React 15.0 to react_on_rails. See #379 by brucek.
  • Support for Node.js server side rendering. See #380 by alleycat and doc
Removed
  • Generator removals to simplify installer. See #364 by jbhatab.
    • Removed options for heroku, boostrap, and the linters from generator.
    • Removed install for the Webpack Dev Server, as we can now do hot reloading with Rails, so the complexity of this feature is not justified. Nevertheless, the setup of React on Rails still supports this setup, just not with the generator.
    • Documentation added for removed installer options.

5.1.1 - 2016-04-04

Fixed
  • Security Fixes: Address failure to sanitize console messages when server rendering and displaying in the browser console. See #366 and #370 by justin808
Added
  • railsContext includes the port number and a boolean if the code is being run on the server or client.

5.1.0 - 2016-04-03

Added

All 5.1.0 changes can be found in #362 by justin808.

  • Generator enhancements
    • Generator adds line to spec/rails_helper.rb so that running specs will ensure assets are compiled.
    • Other small changes to the generator including adding necessary npm scripts to allow React on Rails to build assets.
    • Npm modules updated for generator.
    • Added babel-runtime in to the client/package.json created.
  • Server rendering
    • Added more diagnostics for server rendering.
    • Calls to setTimeout and setInterval are not logged for server rendering unless env TRACE_REACT_ON_RAILS is set to YES.
  • Updated all project npm dependencies to latest.
  • Update to node 5.10.0 for CI.
  • Added babel-runtime as a peer dependency for the npm module.

5.0.0 - 2016-04-01

Added
  • Added railsContext, an object which gets passed always as the second parameter to both React component and Redux store generator functions, both for server and client rendering. This provides data like the current locale, the pathname, etc. The data values are customizable by a new configuration called rendering_extension where you can create a module with a method called rendering_extension. This allows you to add additional values to the Rails Context. Implement one static method called custom_context(view_context) and return a Hash. See #345 by justin808
Changed
  • Previously, you could pass arbitrary additional HTML attributes to react_component. Now, you need to pass them in as a named parameter html_options to react_component.
Breaking Changes
  • You must provide named attributes, including props for view helper react_component. See this commit for an example migration used for reactrails.com.

4.0.3 - 2016-03-17

Fixed
  • ReactOnRailsHelper#react_component: Invalid deprecation message when called with only one parameter, the component name.

4.0.2 - 2016-03-17

Fixed
  • ReactOnRails::Controller#redux_store: 2nd parameter changed to a named parameter props for consistency.

4.0.1 - 2016-03-16

Fixed
  • Switched to heroku buildpacks:set syntax rather than using a .buildpacks file, which is deprecated. See #319 by esauter5. Includes both generator and doc updates.

4.0.0 - 2016-03-14

Added
  • react_on_rails/spec/dummy is a full sample app of React on Rails techniques including the hot reloading of assets from Rails!
  • Added helpers env_stylesheet_link_tag and env_javascript_include_tag to support hot reloading Rails. See the README.md for more details and see the example application in spec/dummy. Also see how this is used in the tutorial: application.html.erb
  • Added optional parameter for ReactOnRails.getStore(name, throwIfMissing = true) so that you can check if a store is defined easily.
  • Added controller module ReactOnRails::Controller. Adds method redux_store to set up Redux stores in the view.
  • Added option defer: true for view helper redux_store. This allows the view helper to specify the props for store hydration, yet still render the props at the bottom of the view.
  • Added view helper redux_store_hydration_data to render the props on the application's layout, near the bottom. This allows for the client hydration data to be parsed after the server rendering, which may result in a faster load time.
  • The checker for outdated bundles before running tests will two configuration options: generated_assets_dir and webpack_generated_files.
  • Better support for Turbolinks 5!
  • Fixed generator check of uncommitted code for foreign languages. See #303 by nmatyukov.
  • Added several parameters used for ensuring webpack assets are built for running tests:
    • config.generated_assets_dir: Directory where your generated webpack assets go. You can have only one directory for this.
    • config.webpack_generated_files: List of files that will get created in the generated_assets_dir. The test runner helper will ensure these generated files are newer than any of the files in the client directory.
Changed
  • Generator default for webpack generated assets is now app/assets/webpack as we use this for both JavaScript and CSS generated assets.
Fixed
  • The test runner "assets up to date checker" is greatly improved.
  • Lots of doc updates!
  • Improved the spec/dummy sample app so that it supports CSS modules, hot reloading, etc, and it can server as a template for a new ReactOnRails installation.
Breaking Changes
  • Deprecated calling redux_store(store_name, props). The API has changed. Use redux_store(store_name, props: props, defer: false) A new option called defer allows the rendering of store hydration at the bottom of the your layout. Place redux_store_hydration_data on your layout.
  • config.server_bundle_js_file has changed. The default value is now blank, meaning no server rendering. Addtionally, if you specify the file name, you should not include the path, as that should be specified in the config.generated_assets_dir.
  • config.generated_assets_dirs has been renamed to config.generated_assets_dir (singular) and it only takes one directory.

3.0.6 - 2016-03-01

Fixed
  • Improved errors when registered store is not found. See #301 by justin808.

3.0.5 - 2016-02-26

Fixed
  • Fixed error in linters rake file for generator. See #299 by mpugach.

3.0.4 - 2016-02-25

Fixed
  • Updated CHANGELOG.md to include contributors for each PR.
  • Fixed config.server_bundle_js file value in generator to match generator setting of server rendering. See #295 by aaronvb.

3.0.3 - 2016-02-21

Fixed
  • Cleaned up code in spec/dummy to latest React and Redux APIs. See #282.
  • Update generator messages with helpful information. See #279.
  • Other small generated comment fixes and doc fixes.

3.0.2 - 2016-02-15

Fixed
  • Fixed missing information in the helpful message after running the base install generator regarding how to run the node server with hot reloading support.

3.0.1 - 2016-02-15

Fixed
  • Fixed several jscs linter issues.

3.0.0 - 2016-02-15

Fixed
  • Fix Bootstrap Sass Append to Gemfile, missing new line. #262.
Added
  • Added helper redux_store and associated JavaScript APIs that allow multiple React components to use the same store. Thus, you initialize the store, with props, separately from the components.
  • Added forman to gemspec in case new dev does not have it globally installed. #248.
  • Support for Turbolinks 5! #270.
  • Added better error messages for ReactOnRails.register(). #273.
Breaking Change
  • Calls to react_component should use a named argument of props. For example, change this:

    <%= react_component("ReduxSharedStoreApp", {}, prerender: false, trace: true) %>

    to

    <%= react_component("ReduxSharedStoreApp", props: {}, prerender: false, trace: true) %>

    You'll get a deprecation message to change this.

  • Renamed ReactOnRails.configure_rspec_to_compile_assets to ReactOnRails::TestHelper.configure_rspec_to_compile_assets. The code has also been optimized to check for whether or not the compiled webpack bundles are up to date or not and will not run if not necessary. If you are using non-standard directories for your generated webpack assets (app/assets/javascripts/generated and app/assets/stylesheets/generated) or have additional directories you wish the helper to check, you need to update your ReactOnRails configuration accordingly. See documentation for how to do this. #253.

  • You have to call ReactOnRails.register to register React components. This was deprecated in v2. #273.

Migration Steps v2 to v3
RSpec.configure do |config|
  # Ensure that if we are running js tests, we are using latest webpack assets
  ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)

2.3.0 - 2016-02-01

Added
  • Added polyfills for setInterval and setTimeout in case other libraries expect these to exist.
  • Added much improved debugging for errors in the server JavaScript webpack file.
  • See #244 for these improvements.

2.2.0 - 2016-01-29

Added
  • New JavaScript API for debugging TurboLinks issues. Be sure to see turbolinks docs. ReactOnRails.setOptions({ traceTurbolinks: true });. Removed the file debug_turbolinks added in 2.1.1. See #243.

2.1.1 - 2016-01-28

Fixed
  • Fixed regression where apps that were not using Turbolinks would not render components on page load.
Added
  • ReactOnRails.render returns a virtualDomElement Reference to your React component's backing instance. See #234.
  • debug_turbolinks helper for debugging turbolinks issues. See turbolinks.
  • Enhanced regression testing for non-turbolinks apps. Runs all tests for dummy app with turbolinks both disabled and enabled.

2.1.0 - 2016-01-26

Added
  • Added EnsureAssetsCompiled feature so that you do not accidentally run tests without properly compiling the JavaScript bundles. Add a line to your rails_helper.rb file to check that the latest Webpack bundles have been generated prior to running tests that may depend on your client-side code. See docs for more detailed instructions. #222
  • Added migration guide for migrating from React-Rails. #219
  • Added React on Rails Doctrine to docs. Discusses the project's motivations, conventions, and principles. #220
  • Added ability to skip display:none style in the generated content tag for a component. Some developers may want to disable inline styles for security reasons. See the skip_display_none configuration option. #218
Changed
  • Changed message when running the dev (a.k.a. "express" server). #227
Fixed
  • Fixed handling of Turbolinks. Code was checking that Turbolinks was installed when it was not yet because some setups load Turbolinks after the bundles. The changes to the code will check if Turbolinks is installed after the page loaded event fires. Code was also added to allow easy debugging of Turbolinks, which should be useful when v5 of Turbolinks is released shortly. Details of how to configure Turbolinks with troubleshooting were added to docs directory. #221
  • Fixed issue with already initialized constant warning appearing when starting a Rails server #226
  • Fixed to make backwards compatible with Ruby v2.0 and updated all Ruby and Node dependencies.

2.0.2

  • Added better messages after generator runs. #210

2.0.1

  • Fixed bug with version matching between gem and npm package.

2.0.0

  • Move JavaScript part of react_on_rails to npm package 'react-on-rails'.
  • Converted JavaScript code to ES6! with tests!
  • No global namespace pollution. ReactOnRails is the only global added.
  • New API. Instead of placing React components on the global namespace, you instead call ReactOnRails.register, passing an object where keys are the names of your components:
import ReactOnRails from 'react-on-rails';
ReactOnRails.register({name: component});

Best done with Object destructing:

  import ReactOnRails from 'react-on-rails';
  ReactOnRails.register(
    {
      Component1,
      Component2
    }
  );

Previously, you used

window.Component1 = Component1;
window.Component2 = Component2;

This would pollute the global namespace. See details in the README.md for more information.

  • Your jade template for the WebpackDevServer setup should use the new API:
  ReactOnRails.render(componentName, props, domNodeId);

such as:

  ReactOnRails.render("HelloWorldApp", {name: "Stranger"}, 'app');
Migration Steps v1 to v2

Example of upgrading

  1. Update the react_on_rails gem.
  2. Remove //= require react_on_rails from any files such as app/assets/javascripts/application.js. This file comes from npm now.
  3. Search you app for 'generator_function' and remove lines in layouts and rb files that contain it. Determination of a generator function is handled automatically.
  4. Find your files where you registered client and server globals, and use the new ReactOnRails.register syntax. Optionally rename the files clientRegistration.jsx and serverRegistration.jsx rather than Globals.
  5. Update your index.jade to use the new API ReactOnRails.render("MyApp", !{props}, 'app');
  6. Update your webpack files per the example commit. Remove globally exposing React and ReactDom, as well as their inclusion in the entry section. These are automatically included now.
  7. Run cd client && npm i --save react-on-rails to get react-on-rails into your client/package.json.
  8. You should also update any other dependencies if possible to match up with the react-webpack-rails-tutorial. This includes updating to Babel 6.
  9. If you want to stick with Babel 5 for a bit, see Issue #238.

1.2.2

Fixed
  • Missing Lodash from generated package.json #175
  • Rails 3.2 could not run generators #182
  • Better placement of jquery_ujs dependency commit b168abd5
  • Add more detailed description when adding --help option to generator commit a9b7d47d
  • Lots of better docs.

1.2.0

Added
  • Support --skip-bootstrap or -b option for generator.
  • Create examples tasks to test generated example apps.
Fixed
  • Fix non-server rendering configuration issues.
  • Fix application.js incorrect overwritten issue.
  • Fix Gemfile dependencies.
  • Fix several generator issues.
Removed
  • Removed templates/client folder.

1.1.1 - 2015-11-28

Added
  • Support for React Router.
  • Error and redirect handling.
  • Turbolinks support.
Fixed
  • Fix several generator-related issues.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

Line1
Line2 no hash

@justin808 justin808 merged commit c4d8687 into main Apr 18, 2026
9 of 10 checks passed
@justin808 justin808 deleted the jg/3155-rsc-docs-followup branch April 18, 2026 08:03
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 18, 2026

Code Review

Overall: Documentation-only PR that is well-scoped and tackles five concrete review follow-ups. The MessageChannel reordering is the most impactful change — leading with the additionalContext approach is strictly better UX for readers. A few accuracy nits and one usability concern below.


Correctness concerns

resolve.fallback: false — inline comment vs paragraph disagree

The inline comment now says "imports resolve to nothing" while the paragraph says "the import resolves to an empty module." These are technically different:

  • With fallback: false in webpack 5, the import resolves to an empty module object ({}), not to nothing/undefined.
  • Accessing any property on the empty object returns undefined at runtime rather than throwing a ReferenceError.

"Resolves to nothing" implies the import is dropped or throws, which is not accurate. The paragraph wording ("empty module") is correct — the inline comment should be updated to match.


Missing client-only React hooks

The expanded hook list is a big improvement, but two client-only hooks are still absent:

Hook Why client-only
useDebugValue Only meaningful inside custom hooks; any custom hook using it lives in a client component
useActionState React 19 hook for form actions; client-only

Given the PR targets React 19.0.4+, useActionState is especially relevant and worth adding to both the "What to look for" list and the audit checklist search string.


Readability / usability

Single-line checklist item with 20+ terms

The audit checklist now collapses all hook names into one enormous search line. This is hard to scan and hard to use practically. Consider replacing it with a ready-to-copy grep/rg command:

grep -rE "useState|useEffect|useLayoutEffect|useInsertionEffect|useContext|useRef|useImperativeHandle|useReducer|useCallback|useMemo|useTransition|useDeferredValue|useId|useSyncExternalStore|useOptimistic|useActionState|useFormStatus|useSelector|useDispatch|connect\(|useNavigate|useLocation|useParams|ReactOnRails\.getStore|ReactOnRails\.authenticityToken" app/javascript/

A single grep invocation is more actionable for larger codebases, and it stays correct even as the list grows.

Browser APIs bullet has grown very long

The parenthetical explaining fetch is accurate but makes the bullet span four lines. Moving the explanation to a sub-bullet or a > **Note:** blockquote would improve readability without losing the content.


Minor nit

The additionalContext code snippet ends with // export from node-renderer.js. The prose immediately above already says "In your node-renderer.js config" and the reference link follows right after. The comment adds noise without adding information — safe to drop.


Verdict: Approve after addressing the resolve.fallback wording inconsistency (accuracy issue); the remaining suggestions are optional.

justin808 added a commit that referenced this pull request Apr 23, 2026
…ons-docs

* origin/main:
  chore: remove redundant --rsc-pro install generator flag (#3105)
  ci: warn (don't fail) on Bencher main regression (#3168)
  test: enable RSpec --profile to surface slowest package tests (#3176)
  fix(node-renderer): expose performance in VM context when supportModules (#3158)
  docs: remove stale immediate_hydration references (#3139) (#3159)
  docs: restore absolute URL for node-renderer testing example (#3179)
  Bump Rspack dependencies to v2 (^2.0.0-0) (#3084)
  chore: remove obsolete webpack <5.106.0 pin (#3175)
  Move Node Renderer entry point to renderer/ directory (#3165)
  docs: address RSC pitfalls review follow-ups (#3155) (#3156)
  docs: remove fabricated DevConsole reference, link verified RSC tools (#2527) (#3163)

# Conflicts:
#	docs/oss/building-features/node-renderer/js-configuration.md
justin808 added a commit that referenced this pull request Apr 23, 2026
…ging' into jg/3122-rolling-deploy-adapter

* origin/jg/3122-unify-renderer-cache-staging: (39 commits)
  fix(specs): boot dummy specs without readline and drop redundant pnpm workspace (#3190)
  docs: add RSC migration success stories page (#1985) (#3162)
  Fix Bencher reporting permanently broken on pushes to main (#3148)
  docs: add example migrations guide (#3126)
  docs: remove defunct guavapass.com reference (#3199)
  chore: remove redundant --rsc-pro install generator flag (#3105)
  ci: warn (don't fail) on Bencher main regression (#3168)
  test: enable RSpec --profile to surface slowest package tests (#3176)
  fix(node-renderer): expose performance in VM context when supportModules (#3158)
  docs: remove stale immediate_hydration references (#3139) (#3159)
  docs: restore absolute URL for node-renderer testing example (#3179)
  Bump Rspack dependencies to v2 (^2.0.0-0) (#3084)
  chore: remove obsolete webpack <5.106.0 pin (#3175)
  Move Node Renderer entry point to renderer/ directory (#3165)
  docs: address RSC pitfalls review follow-ups (#3155) (#3156)
  docs: remove fabricated DevConsole reference, link verified RSC tools (#2527) (#3163)
  Scaffold CI workflow and build scripts for first-run consistency (#3097)
  Add OPTIONAL triage tier and fix recommendations to /address-review (#3161)
  chore: sync Gemfile.lock with term-ansicolor 1.11.3 (#3164)
  Simplify the docs sidebar and Pro landing pages (#3119)
  ...
justin808 added a commit that referenced this pull request Apr 23, 2026
* origin/main:
  fix(specs): boot dummy specs without readline and drop redundant pnpm workspace (#3190)
  docs: add RSC migration success stories page (#1985) (#3162)
  Fix Bencher reporting permanently broken on pushes to main (#3148)
  docs: add example migrations guide (#3126)
  docs: remove defunct guavapass.com reference (#3199)
  chore: remove redundant --rsc-pro install generator flag (#3105)
  ci: warn (don't fail) on Bencher main regression (#3168)
  test: enable RSpec --profile to surface slowest package tests (#3176)
  fix(node-renderer): expose performance in VM context when supportModules (#3158)
  docs: remove stale immediate_hydration references (#3139) (#3159)
  docs: restore absolute URL for node-renderer testing example (#3179)
  Bump Rspack dependencies to v2 (^2.0.0-0) (#3084)
  chore: remove obsolete webpack <5.106.0 pin (#3175)
  Move Node Renderer entry point to renderer/ directory (#3165)
  docs: address RSC pitfalls review follow-ups (#3155) (#3156)

# Conflicts:
#	CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: follow-up fixes for RSC pitfalls review comments (from PR #3087)

1 participant