Skip to content

Auto-install react_on_rails_pro gem when --rsc/--pro flags are used#2439

Open
justin808 wants to merge 2 commits intomasterfrom
jg/2436-auto-install-pro-gem
Open

Auto-install react_on_rails_pro gem when --rsc/--pro flags are used#2439
justin808 wants to merge 2 commits intomasterfrom
jg/2436-auto-install-pro-gem

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Feb 16, 2026

Summary

  • When running rails g react_on_rails:install --rsc (or --pro), the generator now automatically runs bundle add react_on_rails_pro --strict to install the Pro gem
  • Previously, the generator only printed an error but continued creating Pro/RSC config files, leaving the app broken (NameError: uninitialized constant ReactOnRailsPro)
  • The auto-install behavior matches how Shakapacker is handled in the same generator

Test plan

  • Run rails g react_on_rails:install --rsc on a fresh Rails app without react_on_rails_pro in Gemfile
  • Verify the Pro gem is automatically added and installed
  • Verify the generator completes successfully and the app is functional
  • Run rails g react_on_rails:install --rsc --ignore-warnings to test the bypass path

Fixes #2436

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Automatic installation of react_on_rails_pro gem during setup when conditions are met.
  • Enhancements

    • Improved setup workflow with more specific error messages and fallback guidance.
    • Refined user instructions for manual setup when automatic installation fails.

When the install generator is run with --rsc or --pro, the Pro gem is
now automatically added to the Gemfile via `bundle add react_on_rails_pro
--strict`, similar to how Shakapacker is auto-installed.

Previously, the generator would print an error message about the missing
gem but continue creating Pro/RSC config files, leaving the app in a
broken state where any subsequent Rails command would crash with
NameError: uninitialized constant ReactOnRailsPro.

Fixes #2436

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 16, 2026

Walkthrough

This PR enhances the missing_pro_gem? method to automatically attempt installation of the react_on_rails_pro gem via bundle add when Pro features are requested. If auto-install succeeds, the method clears internal state and returns false. Otherwise, it displays updated guidance for manual Gemfile addition.

Changes

Cohort / File(s) Summary
Pro Setup Generator Enhancement
react_on_rails/lib/generators/react_on_rails/pro_setup.rb
Enhanced missing_pro_gem? to attempt automatic bundle add installation of react_on_rails_pro when force flag is true or Pro use is enabled. Updated error messaging to distinguish between missing gem and failed auto-install scenarios, with adjusted logging and exit paths.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Poem

🐰 Hoppy times ahead, no more broken dreams!
Auto-install bundles, smooth as river streams,
Pro gems now install without a manual plea,
RSC setup flows with seamless glee!

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: auto-installing react_on_rails_pro gem when --rsc/--pro flags are used, matching the primary objective.
Linked Issues check ✅ Passed The PR implements the primary requirement from issue #2436: automatically running bundle add react_on_rails_pro when --rsc or --pro flags are used, preventing broken state.
Out of Scope Changes check ✅ Passed All changes are scoped to pro_setup.rb and directly address the auto-install requirement; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jg/2436-auto-install-pro-gem

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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

greptile-apps bot commented Feb 16, 2026

Greptile Summary

This PR adds automatic installation of the react_on_rails_pro gem via bundle add react_on_rails_pro --strict when the --pro or --rsc flags are used with the install generator, following the same pattern used for Shakapacker auto-install. Previously, the generator only printed an error and continued, leaving the app in a broken state.

  • The auto-install approach using Bundler.with_unbundled_env { system("bundle add ...") } is consistent with the existing Shakapacker pattern in install_generator.rb
  • The memoization invalidation at line 59 (@pro_gem_installed = nil) is semantically incorrect — defined?(@pro_gem_installed) still returns truthy for nil, so the memo isn't truly cleared. Should use remove_instance_variable instead
  • Existing tests will break: install_generator_spec.rb (lines 1113-1138) and pro_generator_spec.rb (lines 31-46) don't stub Bundler.with_unbundled_env/system, so they'll attempt a real bundle add in test. Additionally, install_generator_spec.rb:1124 asserts "Try Pro free!" which was removed from the error message
  • The "Try Pro free!" marketing line was removed from the error message — this appears intentional but is a behavior change worth noting

Confidence Score: 2/5

  • This PR has test breakage that must be fixed before merging — existing specs will fail due to unstubbed auto-install calls and a removed assertion string.
  • Score of 2 reflects two concrete issues: (1) existing tests will break because they don't stub the new Bundler.with_unbundled_env/system calls and one test asserts on removed text, and (2) a memoization invalidation bug where @pro_gem_installed = nil doesn't actually clear the defined? guard. The core feature logic is sound and follows established patterns, but the test breakage makes this unsafe to merge as-is.
  • Pay close attention to react_on_rails/lib/generators/react_on_rails/pro_setup.rb (memoization bug, missing test updates) and the corresponding test files install_generator_spec.rb and pro_generator_spec.rb which are not updated in this PR.

Important Files Changed

Filename Overview
react_on_rails/lib/generators/react_on_rails/pro_setup.rb Adds auto-install of react_on_rails_pro via bundle add before falling back to error. Has a memoization invalidation bug (@pro_gem_installed = nil doesn't clear defined? guard) and existing tests are not updated to handle the new Bundler.with_unbundled_env { system(...) } call or the removed "Try Pro free!" text.

Sequence Diagram

sequenceDiagram
    participant User
    participant InstallGenerator
    participant ProSetup as ProSetup#missing_pro_gem?
    participant GeneratorHelper as GeneratorHelper#pro_gem_installed?
    participant Bundler
    participant System as system("bundle add")

    User->>InstallGenerator: rails g react_on_rails:install --pro
    InstallGenerator->>ProSetup: missing_pro_gem?()
    ProSetup->>GeneratorHelper: use_pro?()
    GeneratorHelper-->>ProSetup: true
    ProSetup->>GeneratorHelper: pro_gem_installed?()
    GeneratorHelper-->>ProSetup: false
    Note over ProSetup: NEW: Auto-install attempt
    ProSetup->>Bundler: with_unbundled_env
    Bundler->>System: bundle add react_on_rails_pro --strict
    alt Install succeeds
        System-->>Bundler: true
        Bundler-->>ProSetup: true
        ProSetup->>ProSetup: @pro_gem_installed = nil
        ProSetup-->>InstallGenerator: false (gem not missing)
        InstallGenerator->>InstallGenerator: Continue with setup_pro()
    else Install fails
        System-->>Bundler: false
        Bundler-->>ProSetup: false
        ProSetup->>ProSetup: GeneratorMessages.add_error(...)
        ProSetup-->>InstallGenerator: true (gem is missing)
        InstallGenerator->>User: Show error, abort
    end
Loading

Last reviewed commit: 3d57fea

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

# Try auto-installing (similar to ensure_shakapacker_in_gemfile in install_generator)
puts Rainbow("📝 Adding react_on_rails_pro to Gemfile...").yellow
if Bundler.with_unbundled_env { system("bundle add react_on_rails_pro --strict") }
@pro_gem_installed = nil
Copy link

Choose a reason for hiding this comment

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

Memoization invalidation is incorrect

Setting @pro_gem_installed = nil does not truly clear the memoization in pro_gem_installed? (defined in generator_helper.rb). The guard clause return @pro_gem_installed if defined?(@pro_gem_installed) checks defined?, which returns truthy even when the variable is nil. So subsequent calls to pro_gem_installed? would return nil (falsy), meaning the gem appears uninstalled even after a successful bundle add.

In practice this is low-risk because missing_pro_gem? is only called once per generator run, but the intent is clearly to allow re-detection. Use remove_instance_variable to fully clear the memo, or simply set it to true since the install just succeeded:

Suggested change
@pro_gem_installed = nil
remove_instance_variable(:@pro_gem_installed) if defined?(@pro_gem_installed)

Comment on lines +57 to +61
puts Rainbow("📝 Adding react_on_rails_pro to Gemfile...").yellow
if Bundler.with_unbundled_env { system("bundle add react_on_rails_pro --strict") }
@pro_gem_installed = nil
return false
end
Copy link

Choose a reason for hiding this comment

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

Existing tests will break — auto-install not stubbed and assertions outdated

Two issues with existing specs:

  1. Tests will attempt a real bundle add call. The specs in install_generator_spec.rb (lines 1113-1138) and pro_generator_spec.rb (lines 31-46) stub Gem.loaded_specs and gem_in_lockfile? but do not stub Bundler.with_unbundled_env / system. When missing_pro_gem? is called in tests, it will now attempt a real bundle add react_on_rails_pro --strict command, which will either fail (making the test pass accidentally by falling through to the error path) or hang/produce side effects in CI.

  2. install_generator_spec.rb:1124 asserts expect(error_text).to include("Try Pro free!"). This string was removed from the error message in this PR, so the test will fail.

These tests need to be updated to stub the auto-install attempt and remove the outdated assertion. For example:

before do
  allow(Bundler).to receive(:with_unbundled_env).and_return(false)
end

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.

In `@react_on_rails/lib/generators/react_on_rails/pro_setup.rb`:
- Around line 58-60: The memoization reset is incorrect: in the block that runs
`bundle add react_on_rails_pro` (inside the `pro_gem_installed?` flow) remove
the memoized instance variable rather than assigning nil so subsequent calls
will re-evaluate; specifically, after a successful Bundler.with_unbundled_env
system call, call remove_instance_variable(:`@pro_gem_installed`) (or
alternatively set `@pro_gem_installed = true`) instead of `@pro_gem_installed =
nil` so the `defined?(`@pro_gem_installed`)` guard in `pro_gem_installed?` behaves
correctly.

Comment on lines +58 to +60
if Bundler.with_unbundled_env { system("bundle add react_on_rails_pro --strict") }
@pro_gem_installed = nil
return false
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's find and read the pro_setup.rb file to see the relevant code
fd "pro_setup.rb" --type f

Repository: shakacode/react_on_rails

Length of output: 125


🏁 Script executed:

# Read the pro_setup.rb file to understand the context of lines 58-60
cat -n react_on_rails/lib/generators/react_on_rails/pro_setup.rb | head -100

Repository: shakacode/react_on_rails

Length of output: 4504


🏁 Script executed:

# Also search for the pro_gem_installed? method definition
rg -n "def pro_gem_installed?" -A 5 --type ruby

Repository: shakacode/react_on_rails

Length of output: 687


🏁 Script executed:

# And find the missing_pro_gem? method to understand the full context
rg -n "def missing_pro_gem?" -A 20 --type ruby

Repository: shakacode/react_on_rails

Length of output: 2281


🏁 Script executed:

#!/bin/bash
# Find all callers of missing_pro_gem?
rg -n "missing_pro_gem?" --type ruby -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 7403


🏁 Script executed:

#!/bin/bash
# Also check what happens after missing_pro_gem? is called - look at the calling methods
rg -n "missing_pro_gem\?" -B 5 -A 5 --type ruby

Repository: shakacode/react_on_rails

Length of output: 12125


🏁 Script executed:

#!/bin/bash
# Check the generator flow - see if pro_gem_installed? is called after missing_pro_gem? returns
rg -n "pro_gem_installed?" -B 3 -A 3 lib/generators/react_on_rails/install_generator.rb

Repository: shakacode/react_on_rails

Length of output: 158


🏁 Script executed:

#!/bin/bash
# Check if pro_gem_installed? is called in the setup flow or initialization
rg -n "pro_gem_installed?" lib/generators/react_on_rails/ --type ruby

Repository: shakacode/react_on_rails

Length of output: 138


🏁 Script executed:

#!/bin/bash
# Find the correct path for install_generator
find . -name "install_generator.rb" -type f

Repository: shakacode/react_on_rails

Length of output: 135


🏁 Script executed:

#!/bin/bash
# Search for pro_gem_installed? calls in the codebase
rg -n "pro_gem_installed?" --type ruby -l

Repository: shakacode/react_on_rails

Length of output: 190


🏁 Script executed:

#!/bin/bash
# Check all calls to pro_gem_installed? in the relevant files
rg -n "pro_gem_installed?" react_on_rails/lib/generators/react_on_rails/pro_setup.rb react_on_rails/lib/generators/react_on_rails/generator_helper.rb -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 2471


🏁 Script executed:

#!/bin/bash
# Check if install_generator has any references to pro_gem_installed? or missing_pro_gem?
rg -n "pro_gem_installed?|missing_pro_gem?" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 328


🏁 Script executed:

#!/bin/bash
# Check where installation_prerequisites_met? is called to understand generator flow
rg -n "installation_prerequisites_met?" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 3 -A 3

Repository: shakacode/react_on_rails

Length of output: 855


🏁 Script executed:

#!/bin/bash
# Check if pro_setup is called and if it uses pro_gem_installed?
rg -n "setup_pro|include ProSetup" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 193


🏁 Script executed:

#!/bin/bash
# Look at the perform method to understand the full generator execution flow
grep -n "def perform" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -A 20

Repository: shakacode/react_on_rails

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Check the invoke_generators method to see what happens after prerequisites are met
rg -n "def invoke_generators" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -A 15

Repository: shakacode/react_on_rails

Length of output: 894


🏁 Script executed:

#!/bin/bash
# Check if any template or subsequent operation calls pro_gem_installed? after prerequisites check
rg -n "setup_pro" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Search for all calls to setup_pro in the entire generators directory
rg -n "setup_pro" ./react_on_rails/lib/generators/react_on_rails/ -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 1206


🏁 Script executed:

#!/bin/bash
# Check the base generator to see if it calls setup_pro
find ./react_on_rails/lib/generators -name "*.rb" -exec grep -l "setup_pro" {} \;

Repository: shakacode/react_on_rails

Length of output: 191


🏁 Script executed:

#!/bin/bash
# Check the pro_generator prerequisites_met? method
rg -n "def prerequisites_met?" ./react_on_rails/lib/generators/react_on_rails/pro_generator.rb -A 5

Repository: shakacode/react_on_rails

Length of output: 288


🏁 Script executed:

#!/bin/bash
# Check how pro_generator is invoked from install_generator
rg -n "invoke.*pro_generator\|:pro" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Search for invoke calls in install_generator that might trigger pro_generator
rg -n "invoke.*pro\|--pro" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 1 -A 1

Repository: shakacode/react_on_rails

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Check base generator to see how it handles pro flag
rg -n "def perform|setup_pro\|--pro" ./react_on_rails/lib/generators/react_on_rails/base_generator.rb -B 2 -A 5

Repository: shakacode/react_on_rails

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Find all generator files to understand the structure
find ./react_on_rails/lib/generators -name "*.rb" -type f | head -20

Repository: shakacode/react_on_rails

Length of output: 1562


🏁 Script executed:

#!/bin/bash
# Search for how Pro is set up in the invoke flow
rg -n "options\[:pro\]|options\[:rsc\]" ./react_on_rails/lib/generators/react_on_rails/install_generator.rb -B 2 -A 2

Repository: shakacode/react_on_rails

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Search for pro flag handling in install_generator
cat -n ./react_on_rails/lib/generators/react_on_rails/install_generator.rb | grep -A 5 -B 5 "pro\|rsc" | head -100

Repository: shakacode/react_on_rails

Length of output: 4833


🏁 Script executed:

#!/bin/bash
# Look at the base generator to see how it handles pro/rsc
cat -n ./react_on_rails/lib/generators/react_on_rails/base_generator.rb | head -150

Repository: shakacode/react_on_rails

Length of output: 6916


🏁 Script executed:

#!/bin/bash
# Check test files to see if they reuse generator instances
rg -n "missing_pro_gem?" ./react_on_rails/spec/react_on_rails/generators/ -B 3 -A 5

Repository: shakacode/react_on_rails

Length of output: 8195


Reset memoization correctly by removing the instance variable instead of setting it to nil.

After a successful bundle add react_on_rails_pro, the code sets @pro_gem_installed = nil to clear the memoization. However, pro_gem_installed? guards with return @pro_gem_installed if defined?(@pro_gem_installed). Since nil keeps the variable defined?, subsequent calls return nil rather than re-evaluating whether the gem is installed.

Proposed fix
         if Bundler.with_unbundled_env { system("bundle add react_on_rails_pro --strict") }
-          `@pro_gem_installed` = nil
+          remove_instance_variable(:`@pro_gem_installed`) if defined?(`@pro_gem_installed`)
           return false
         end

Alternatively, set @pro_gem_installed = true since the bundle add succeeded.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if Bundler.with_unbundled_env { system("bundle add react_on_rails_pro --strict") }
@pro_gem_installed = nil
return false
if Bundler.with_unbundled_env { system("bundle add react_on_rails_pro --strict") }
remove_instance_variable(:`@pro_gem_installed`) if defined?(`@pro_gem_installed`)
return false
🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In `@react_on_rails/lib/generators/react_on_rails/pro_setup.rb` around lines 58 -
60, The memoization reset is incorrect: in the block that runs `bundle add
react_on_rails_pro` (inside the `pro_gem_installed?` flow) remove the memoized
instance variable rather than assigning nil so subsequent calls will
re-evaluate; specifically, after a successful Bundler.with_unbundled_env system
call, call remove_instance_variable(:`@pro_gem_installed`) (or alternatively set
`@pro_gem_installed = true`) instead of `@pro_gem_installed = nil` so the
`defined?(`@pro_gem_installed`)` guard in `pro_gem_installed?` behaves correctly.

@justin808 justin808 added the release:16.4.0-must-have Must-have for 16.4.0: critical bug/perf/usability label Feb 25, 2026
AbanoubGhadban added a commit that referenced this pull request Feb 28, 2026
…ability (#2466)

## Summary

LLMs consistently fail to generate correct React on Rails Pro setup
code. After deep analysis
([#2465](#2465)), the
root causes are:

1. **npm packages have no READMEs** — npm READMEs are the #1 training
signal for LLMs
2. **No single quick-start page** — correct setup is spread across 4+
doc pages
3. **Incorrect example in Pro gem README** — uses old
`@shakacode-tools/` scoped name and deprecated `bundlePath`

This PR addresses the low-effort, high-impact recommendations from
#2465.

### Changes

- **Add README.md to all 3 npm packages** (`react-on-rails`,
`react-on-rails-pro`, `react-on-rails-pro-node-renderer`) with correct
API examples, config option tables, and package relationship docs
- **Fix incorrect example in Pro gem README** — old scoped package name
`@shakacode-tools/react-on-rails-pro-node-renderer` →
`react-on-rails-pro-node-renderer`, deprecated `bundlePath` →
`serverBundleCachePath`
- **Add `docs/getting-started/pro-quick-start.md`** — single
self-contained guide for Pro setup from scratch using the `--pro`
generator
- **Add `llms.txt`** at repo root — follows the [llms.txt
convention](https://llmstxt.org/) providing LLMs with correct package
relationships, API names, and config keys

### What this does NOT include

- Generator changes (`--pro`/`--rsc`) — already merged in #2284
- Auto-install of `react_on_rails_pro` gem — open in #2439

## Test plan

- [ ] Verify npm README content is accurate against current API
(TypeScript types in `packages/react-on-rails-pro-node-renderer/lib/`)
- [ ] Verify Pro quick-start guide steps work with a fresh `rails new` +
`rails generate react_on_rails:install --pro`
- [ ] Verify `llms.txt` config examples match the generator templates in
`lib/generators/react_on_rails/templates/pro/`
- [ ] Confirm READMEs will be included in npm publish (no `files` field
excluding them, or `files` field includes `README.md`)

Closes #2465

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Added a Pro quick-start guide with step‑by‑step setup, SSR
verification, Server Components, configuration examples,
troubleshooting, and next steps.
* Added/expanded package READMEs and Node renderer documentation
covering installation, configuration, usage, customization, and links.
* Replaced private-repo and private-publishing references with public
equivalents and clarified onboarding wording.
* **Chores**
  * Included READMEs in the published file lists for two packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:16.4.0-must-have Must-have for 16.4.0: critical bug/perf/usability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RSC generator doesn't add react_on_rails_pro gem to Gemfile

1 participant