Skip to content

Conversation

AbanoubGhadban
Copy link
Collaborator

@AbanoubGhadban AbanoubGhadban commented Oct 8, 2025

Summary

This PR moves the Pro Ruby code from lib/react_on_rails/pro/ to the main MIT-licensed codebase at lib/react_on_rails/. This change improves marketing visibility while maintaining proper separation of Pro features.

Changes

Files Moved

  • lib/react_on_rails/pro/helper.rblib/react_on_rails/pro_helper.rb
  • lib/react_on_rails/pro/utils.rblib/react_on_rails/pro_utils.rb

Code Changes

  • Removed Pro license headers (now MIT licensed)
  • Changed namespace from ReactOnRails::Pro:: to ReactOnRails::
  • Removed Pro warning badge functionality (no longer needed)
  • Deleted lib/react_on_rails/pro/ directory entirely

Documentation Updates

  • Updated LICENSE.md to reflect lib/react_on_rails/ is entirely MIT licensed
  • Updated docs/MONOREPO_MERGER_PLAN.md to match new license structure

Rationale

Marketing Benefits:

  • All React on Rails users now see the Pro feature signaling code
  • Non-intrusive way to inform users about Pro features
  • Helps with feature discovery

Technical Benefits:

  • Ruby code just toggles/signals Pro features
  • Actual functionality remains in Pro npm package (packages/react-on-rails-pro/)
  • Users cannot hack Ruby code to enable Pro features without the Pro package
  • Clean separation: Ruby signaling in MIT, functionality in Pro packages

License Compliance:

  • Core logic stays in Pro npm package (properly licensed)
  • Ruby code becomes MIT licensed (used for signaling only)
  • No security risk from MIT licensing the Ruby code

Testing

  • All existing tests should pass
  • No behavioral changes for users with or without Pro license
  • Pro features still require valid Pro license and Pro npm package

Closes #1854 (supersedes previous approach)

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • New Features

    • None.
  • Documentation

    • Updated licensing: entire React on Rails library now covered by MIT; Pro license scoped to designated Pro packages.
    • Revised merger plan docs to reflect new license boundaries.
  • Refactor

    • Simplified Pro helpers and utilities structure for clearer usage and consistency. No expected changes for licensed users.
  • Chores

    • Removed outdated Pro license notice content from the library.

Moved lib/react_on_rails/pro/ code to MIT-licensed locations:
- lib/react_on_rails/pro/helper.rb → lib/react_on_rails/pro_helper.rb
- lib/react_on_rails/pro/utils.rb → lib/react_on_rails/pro_utils.rb

Changes:
- Removed Pro license headers from moved files
- Changed namespace from ReactOnRails::Pro:: to ReactOnRails::
- Removed Pro warning badge functionality (no longer needed)
- Deleted lib/react_on_rails/pro/ directory entirely
- Updated LICENSE.md to reflect all lib/react_on_rails/ is MIT
- Updated documentation references

Benefits:
- Ruby signaling code now in MIT gem for marketing visibility
- Actual functionality still requires Pro npm package
- Clean license boundaries maintained
- Users can't bypass Pro features by editing Ruby code
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Walkthrough

Licensing text updated to MIT-license all of lib/react_on_rails/. Pro-licensed NOTICE and modules under lib/react_on_rails/pro/ were removed. New flat Pro helper/utils introduced at lib/react_on_rails/pro_helper.rb and lib/react_on_rails/pro_utils.rb. Helper include paths and requires were adjusted. Render options now reference ReactOnRails::ProUtils.

Changes

Cohort / File(s) Summary
Licensing & Docs
LICENSE.md, docs/MONOREPO_MERGER_PLAN.md
Updated license scope to include all of lib/react_on_rails/; removed explicit Pro subdirectory references. Plan doc reflects new licensing boundaries.
Core Helper & Render Options
lib/react_on_rails/helper.rb, lib/react_on_rails/react_component/render_options.rb
Switched include from ReactOnRails::Pro::Helper to ReactOnRails::ProHelper; updated requires and call sites from pro/utils to pro_utils.
Removed legacy Pro namespace
lib/react_on_rails/pro/NOTICE, lib/react_on_rails/pro/helper.rb, lib/react_on_rails/pro/utils.rb
Deleted Pro NOTICE and the ReactOnRails::Pro::Helper and ReactOnRails::Pro::Utils modules.
New flat Pro helpers/utils
lib/react_on_rails/pro_helper.rb, lib/react_on_rails/pro_utils.rb
Added ReactOnRails::ProHelper (component/store script generation with optional immediate hydration) and ReactOnRails::ProUtils (license check and pro-option disabling).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor View
  participant Helper as ReactOnRails::Helper
  participant ProUtils as ReactOnRails::ProUtils
  participant ProHelper as ReactOnRails::ProHelper
  Note over View,Helper: Component render
  View->>Helper: generate_component_script(render_options)
  Helper->>ProUtils: disable_pro_render_options_if_not_licensed(options)
  ProUtils-->>Helper: { raw_options, explicitly_disabled_pro_options }
  Helper->>ProHelper: generate_component_script(processed_options)
  ProHelper-->>Helper: main script + optional immediate script
  Helper-->>View: HTML scripts
  rect rgb(245,245,255)
  Note right of ProHelper: Immediate hydration path (if enabled)
  end
Loading
sequenceDiagram
  autonumber
  actor View
  participant Helper as ReactOnRails::Helper
  participant ProUtils as ReactOnRails::ProUtils
  participant ProHelper as ReactOnRails::ProHelper
  Note over View,Helper: Store hydration
  View->>Helper: generate_store_script(store_data)
  Helper->>ProUtils: disable_pro_render_options_if_not_licensed(options)
  ProUtils-->>Helper: { raw_options, explicitly_disabled_pro_options }
  Helper->>ProHelper: generate_store_script(processed_store_data)
  ProHelper-->>Helper: main script + optional immediate script
  Helper-->>View: HTML scripts
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • justin808
  • Romex91
  • alexeyr-ci2

Poem

A bunny taps keys with careful delight,
Pro bits hopped out, MIT shines bright.
Scripts now hydrate with a gentle breeze,
Options checked swiftly, rendered with ease.
Licenses sorted, paths made new—
Thump-thump goes progress, clean and true. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The changes remove Pro helpers and utilities from the core and adjust licensing, but they do not relocate Pro functionality into the Pro gem, implement the data enhancement pattern, move the immediate_hydration configuration, or include the required tests to stub and enhance behavior as specified by issue #1854. To comply with issue #1854, refactor generate_component_script and generate_store_script to collect data in the core and delegate enhancements to the react_on_rails_pro gem, move the immediate_hydration configuration from the core to the Pro gem, implement the required enhance_component_script_data and enhance_store_script_data methods in the Pro gem, remove related utilities from the core, and add tests verifying immediate hydration behavior and Pro gem stubability.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary change of migrating Pro Ruby code to be covered under the MIT license, which directly reflects the main purpose of the pull request.
Out of Scope Changes Check ✅ Passed All modifications relate directly to removing the lib/react_on_rails/pro directory, updating namespaces and licensing, and adjusting documentation and require paths to reflect the relocation and relicensing of Pro code, with no extraneous or unrelated changes.
✨ 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 move-pro-code-to-mit-license

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.

@claude
Copy link

claude bot commented Oct 8, 2025

Code Review for PR 1855: Move Pro Ruby code to MIT license - I have reviewed the changes and have detailed feedback. Main strengths: (1) Clear intent and rationale with excellent documentation (2) Consistent namespace migration from ReactOnRails::Pro:: to ReactOnRails:: (3) Proper file hygiene with trailing newlines (4) Complete cleanup of Pro license headers. Main concerns: (1) Removed Pro warning badge functionality without replacement - is this intentional? (2) generate_store_script still calls disable_pro_render_options_if_not_licensed but ignores the explicitly_disabled_pro_options result (3) No test file changes in PR - need to verify tests still pass. Code quality notes: Redundant .strip_heredoc on squiggly heredoc at line 53 of pro_helper.rb. Inconsistent string interpolation styles between line 27 and 53. Security: Good use of escape_javascript for XSS prevention. Before merging: Run bundle exec rubocop, run full test suite, verify namespace migration is complete. Overall this is a well-structured refactoring with clear business value. Once the concerns about removed warning functionality and test coverage are addressed, this should be ready to merge.

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: 0

🧹 Nitpick comments (2)
lib/react_on_rails/pro_helper.rb (2)

38-48: Remove unnecessary .html_safe call on attribute value.

Line 45: Calling .html_safe on store_name before using it as an attribute value is unnecessary and potentially unsafe. Rails' content_tag automatically escapes attribute values, and marking the value as html_safe bypasses this protection. While store_name is typically a trusted value, this violates security best practices.

Apply this diff to remove the unnecessary call:

-                                         "data-js-react-on-rails-store" => redux_store_data[:store_name].html_safe,
+                                         "data-js-react-on-rails-store" => redux_store_data[:store_name],

50-60: Consider removing redundant .strip_heredoc.

Line 53: The .strip_heredoc call is redundant when using the <<~ heredoc syntax, which already strips leading indentation in Ruby 2.3+. While harmless, removing it would make the code cleaner.

Apply this diff to remove the redundant call:

-        immediate_script = content_tag(:script, <<~JS.strip_heredoc.html_safe
+        immediate_script = content_tag(:script, <<~JS.html_safe
           typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsStoreLoaded('#{escaped_store_name}');
         JS
         )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7bce94a and 9601c37.

📒 Files selected for processing (9)
  • LICENSE.md (1 hunks)
  • docs/MONOREPO_MERGER_PLAN.md (1 hunks)
  • lib/react_on_rails/helper.rb (1 hunks)
  • lib/react_on_rails/pro/NOTICE (0 hunks)
  • lib/react_on_rails/pro/helper.rb (0 hunks)
  • lib/react_on_rails/pro/utils.rb (0 hunks)
  • lib/react_on_rails/pro_helper.rb (1 hunks)
  • lib/react_on_rails/pro_utils.rb (1 hunks)
  • lib/react_on_rails/react_component/render_options.rb (2 hunks)
💤 Files with no reviewable changes (3)
  • lib/react_on_rails/pro/helper.rb
  • lib/react_on_rails/pro/NOTICE
  • lib/react_on_rails/pro/utils.rb
🧰 Additional context used
📓 Path-based instructions (2)
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • lib/react_on_rails/react_component/render_options.rb
  • lib/react_on_rails/pro_utils.rb
  • lib/react_on_rails/pro_helper.rb
  • lib/react_on_rails/helper.rb
**/*.{js,jsx,ts,tsx,css,scss,json,yml,yaml,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Prettier is the sole authority for formatting all non-Ruby files; never manually format them

Files:

  • docs/MONOREPO_MERGER_PLAN.md
  • LICENSE.md
🧠 Learnings (5)
📓 Common learnings
Learnt from: alexeyr-ci2
PR: shakacode/react_on_rails#1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/react_component/render_options.rb
  • lib/react_on_rails/pro_utils.rb
  • lib/react_on_rails/pro_helper.rb
  • lib/react_on_rails/helper.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • lib/react_on_rails/react_component/render_options.rb
  • lib/react_on_rails/pro_utils.rb
  • lib/react_on_rails/helper.rb
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/react_on_rails/pro_helper.rb
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
PR: shakacode/react_on_rails#1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • lib/react_on_rails/helper.rb
🧬 Code graph analysis (3)
lib/react_on_rails/react_component/render_options.rb (1)
lib/react_on_rails/pro_utils.rb (1)
  • disable_pro_render_options_if_not_licensed (13-35)
lib/react_on_rails/pro_utils.rb (1)
lib/react_on_rails/utils.rb (1)
  • react_on_rails_pro_licence_valid? (249-262)
lib/react_on_rails/pro_helper.rb (3)
lib/react_on_rails/helper.rb (1)
  • json_safe_and_pretty (350-361)
lib/react_on_rails/react_component/render_options.rb (5)
  • client_props (34-46)
  • dom_id (52-60)
  • trace (82-84)
  • store_dependencies (142-144)
  • immediate_hydration (102-104)
lib/react_on_rails/pro_utils.rb (1)
  • disable_pro_render_options_if_not_licensed (13-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: claude-review
  • GitHub Check: build
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: markdown-link-check
  • GitHub Check: build-and-test
🔇 Additional comments (10)
LICENSE.md (1)

14-14: LGTM! License scope correctly updated.

The MIT license now properly covers the entire lib/react_on_rails/ directory (including its subdirectories), aligning with the PR's objective to move Pro Ruby signaling code under MIT licensing. Pro licensing is correctly scoped to the separate packages and directories.

docs/MONOREPO_MERGER_PLAN.md (1)

375-375: LGTM! Documentation aligns with license restructuring.

The monorepo plan now correctly documents that lib/react_on_rails/ (entire directory) is MIT-licensed, consistent with the changes in LICENSE.md and the removal of the nested Pro directory structure.

lib/react_on_rails/react_component/render_options.rb (2)

4-4: LGTM! Require path updated to new module structure.

The require path correctly references the new flat module structure (react_on_rails/pro_utils instead of the nested react_on_rails/pro/utils).


19-19: LGTM! Namespace correctly updated.

The call site properly uses the new flattened namespace ReactOnRails::ProUtils instead of the previous nested ReactOnRails::Pro::Utils, maintaining the same functionality while aligning with the restructured module organization.

lib/react_on_rails/helper.rb (2)

14-14: LGTM! Require path updated for new module structure.

The require correctly references the new flat file structure (react_on_rails/pro_helper instead of the nested react_on_rails/pro/helper).


19-19: LGTM! Module inclusion updated to new namespace.

The include statement properly uses the flattened namespace ReactOnRails::ProHelper instead of the previous nested ReactOnRails::Pro::Helper, maintaining functionality while aligning with the restructured module organization.

lib/react_on_rails/pro_utils.rb (2)

9-11: LGTM! Clean delegation to license validation.

The method provides a clear interface for checking Pro feature availability by delegating to the established license validation logic.


13-35: LGTM! Pro option disabling logic is sound.

The method correctly:

  • Returns unchanged options when Pro features are supported
  • Duplicates options to avoid mutating the original when Pro features are not supported
  • Identifies enabled Pro options by checking both explicit option values and global configuration fallbacks
  • Disables only the Pro options that were explicitly enabled
  • Returns both the modified options and the list of disabled options for transparency

The logic properly handles the case where an option might not be explicitly set in raw_options by falling back to the global configuration.

lib/react_on_rails/pro_helper.rb (2)

1-6: LGTM!

The module declaration follows Ruby best practices with frozen_string_literal: true and the flat namespace structure aligns with the PR objective of moving from ReactOnRails::Pro:: to ReactOnRails::.


7-34: Licensing check handled in RenderOptions initializer
ReactOnRails::ReactComponent::RenderOptions#initialize (lib/react_on_rails/react_component/render_options.rb:19) invokes ProUtils.disable_pro_render_options_if_not_licensed, so generate_component_script receives already-validated options.

Removed all test contexts for Pro warning badge functionality since
the badge feature has been removed from the codebase.

Tests removed:
- react_component Pro license warning contexts
- react_component_hash Pro license warning contexts
- redux_store Pro license warning contexts
@claude
Copy link

claude bot commented Oct 8, 2025

Code Review

I've reviewed PR #1855 that moves Pro Ruby code from lib/react_on_rails/pro/ to the main MIT-licensed codebase. Here's my analysis:

Strengths

  1. Clean Namespace Refactoring: The migration from ReactOnRails::Pro:: to ReactOnRails::ProHelper and ReactOnRails::ProUtils is well-executed and maintains clear module separation.

  2. Appropriate Code Simplification: Removing the Pro warning badge functionality makes sense since this is now signaling code rather than gated functionality. The actual Pro features remain properly protected in the Pro npm package.

  3. Documentation Updates: LICENSE.md and MONOREPO_MERGER_PLAN.md are correctly updated to reflect the new structure.

  4. Test Coverage: The removal of Pro license warning tests is appropriate since that functionality no longer exists in this layer.

🔍 Code Quality Observations

1. Simplified Logic Flow (lib/react_on_rails/pro_helper.rb)
The new generate_component_script method is cleaner:

  • Removed unused pro_warning_badge variable and logic
  • More straightforward conditional for immediate hydration
  • Better readability overall

2. Reduced Complexity (lib/react_on_rails/pro_utils.rb)
The disable_pro_render_options_if_not_licensed method still returns explicitly_disabled_pro_options but it is no longer used in the new code. Consider:

  • Removing this from the return hash if it is truly unused
  • Or documenting why it is kept for backward compatibility

⚠️ Potential Issues

1. Unused Return Value (lib/react_on_rails/pro_helper.rb:39)

pro_options_check_result = ReactOnRails::ProUtils.disable_pro_render_options_if_not_licensed(redux_store_data)
redux_store_data = pro_options_check_result[:raw_options]
# explicitly_disabled_pro_options is returned but never used

The explicitly_disabled_pro_options key is no longer consumed. This creates technical debt. Recommendation: Update ProUtils.disable_pro_render_options_if_not_licensed to only return what is needed, or document why the full structure is maintained.

2. Missing Newline at EOF
Several new files may be missing trailing newlines:

  • lib/react_on_rails/pro_helper.rb
  • lib/react_on_rails/pro_utils.rb

Per CLAUDE.md: "ALWAYS ensure files end with a newline character". Please verify and add if needed.

3. RuboCop Compliance
Per CLAUDE.md: "ALWAYS run bundle exec rubocop and fix ALL violations". Please ensure this was run and passes with zero offenses.

🎯 Recommendations

  1. Verify Linting: Run bundle exec rubocop to ensure compliance before merge
  2. Check Trailing Newlines: Verify all new files end with newlines
  3. Consider Cleanup: Evaluate if explicitly_disabled_pro_options return value can be removed from ProUtils for simplicity
  4. Documentation: Consider adding inline comments explaining that this Ruby code is for signaling only, with actual Pro functionality in the npm package

🔒 Security & Architecture

Well-designed separation: The approach correctly keeps actual Pro functionality in the npm package while using Ruby for signaling. Users cannot hack Ruby code to enable Pro features without the Pro package.

License compliance: The change properly moves signaling code to MIT while keeping core Pro logic protected.

📊 Summary

This is a well-executed refactoring with clear architectural benefits. The code is cleaner and the marketing strategy makes sense. The main concerns are:

  • Ensuring linting compliance
  • Handling unused return values
  • File formatting (trailing newlines)

Verdict: Approve with minor cleanup suggestions. The technical approach is sound and the changes achieve the stated goals effectively.


Generated by Claude Code

Moved lib/react_on_rails/pro/ code to MIT-licensed locations:
- lib/react_on_rails/pro/helper.rb → lib/react_on_rails/pro_helper.rb
- lib/react_on_rails/pro/utils.rb → lib/react_on_rails/pro_utils.rb

Changes:
- Removed Pro license headers from moved files
- Changed namespace from ReactOnRails::Pro:: to ReactOnRails::
- PRESERVED Pro warning badge functionality (shows when Pro features used without license)
- Deleted lib/react_on_rails/pro/ directory
- Updated LICENSE.md to reflect all lib/react_on_rails/ is MIT
- Updated documentation references

Benefits:
- Ruby signaling code now in MIT gem for marketing visibility
- Pro warning badge alerts users about Pro features
- Actual functionality still requires Pro npm package
- Clean license boundaries maintained
@claude
Copy link

claude bot commented Oct 8, 2025

Pull Request Review - PR #1855: Move Pro Ruby code to MIT license

Summary

This PR refactors the Pro Ruby code by moving it from lib/react_on_rails/pro/ to the main codebase and changing the namespace from ReactOnRails::Pro:: to ReactOnRails::. The core functionality remains unchanged, with only organizational and licensing changes.


Strengths

  1. Clean Refactoring: The namespace changes are consistent and well-executed with all references updated correctly in helper.rb and render_options.rb

  2. Maintains Security: The approach is sound - moving only the signaling code to MIT while keeping the actual Pro functionality in the npm package prevents unauthorized feature usage.

  3. Test Coverage: Existing tests appear comprehensive with good coverage of Pro feature detection, warning badge generation, immediate_hydration feature toggling, and both component and store hydration scenarios.

  4. Documentation: LICENSE.md and docs are properly updated to reflect the new structure.

  5. No Breaking Changes: The refactoring maintains backward compatibility - all public APIs remain functionally identical.


Observations and Minor Concerns

1. Missing Newline Character

Per CLAUDE.md requirements, all files MUST end with a newline character. Please verify lib/react_on_rails/pro_helper.rb:106 and lib/react_on_rails/pro_utils.rb:37 end with newlines.

2. RuboCop Compliance

According to CLAUDE.md, you MUST run bundle exec rubocop before every commit. Please run bundle exec rubocop on the new files and fix any violations.

3. Code Quality - Minor Suggestions

Redundant conditionals: The check in disabled_pro_features_message (line 96) is redundant since pro_warning_badge_if_needed already guards this. Consider removing.

Magic strings: Consider extracting URLs and messages to constants for maintainability.

4. Test Coverage

Please verify tests properly import the new namespaces and handle edge cases like nil explicitly_disabled_pro_options.


Security and Licensing

Security posture is sound - moving signaling code to MIT does not create a bypass vector. Pro functionality enforcement still occurs in the Pro npm package via ReactOnRails::Utils.react_on_rails_pro_licence_valid?.

Licensing is clear - LICENSE.md accurately reflects the new structure with proper separation between MIT (signaling) and Pro (functionality).


Pre-Merge Checklist

  • bundle exec rubocop passes with zero offenses
  • All files end with newline characters
  • All tests pass: rake run_rspec
  • Manual testing of Pro feature warnings
  • CI pipeline is green

Recommendation

Approve with minor fixes required - This is a well-executed refactoring. The only blockers are:

  1. Ensure trailing newlines (CRITICAL per CLAUDE.md)
  2. Run and pass bundle exec rubocop (CRITICAL per CLAUDE.md)
  3. Consider minor code quality improvements (OPTIONAL)

Great work maintaining test coverage and documentation!

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: 0

🧹 Nitpick comments (2)
lib/react_on_rails/pro_helper.rb (2)

61-64: Redundant strip_heredoc with squiggly heredoc.

The <<~ syntax already strips leading whitespace, making the .strip_heredoc call redundant. While harmless, removing it would simplify the code.

-                                  immediate_script = content_tag(:script, <<~JS.strip_heredoc.html_safe
+                                  immediate_script = content_tag(:script, <<~JS.html_safe
                                     typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsStoreLoaded('#{escaped_store_name}');
                                   JS
                                   )

74-94: Consider explicit HTML attribute escaping for defense in depth.

While the tooltip_text is built from controlled option names (from PRO_ONLY_OPTIONS constant), interpolating directly into the HTML title attribute without explicit escaping could be improved for defensive programming.

Since the option names are controlled and unlikely to contain HTML special characters, the current implementation is safe. However, for defense in depth, you could use ERB::Util.html_escape or Rails' h helper on tooltip_text before interpolation:

tooltip_text = ERB::Util.html_escape("#{disabled_features_message} Click to learn more.")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7fccea and 5831e5c.

📒 Files selected for processing (1)
  • lib/react_on_rails/pro_helper.rb (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • lib/react_on_rails/pro_helper.rb
🧠 Learnings (3)
📓 Common learnings
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/pro_helper.rb
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
PR: shakacode/react_on_rails#1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/react_on_rails/pro_helper.rb
🧬 Code graph analysis (1)
lib/react_on_rails/pro_helper.rb (3)
lib/react_on_rails/helper.rb (1)
  • json_safe_and_pretty (350-361)
lib/react_on_rails/react_component/render_options.rb (5)
  • client_props (34-46)
  • dom_id (52-60)
  • trace (82-84)
  • store_dependencies (142-144)
  • immediate_hydration (102-104)
lib/react_on_rails/pro_utils.rb (1)
  • disable_pro_render_options_if_not_licensed (13-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: dummy-app-integration-tests (3.2, 20)
  • GitHub Check: dummy-app-integration-tests (3.4, 22)
  • GitHub Check: build
  • GitHub Check: claude-review
  • GitHub Check: markdown-link-check
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: rspec-package-tests (3.2, latest)
  • GitHub Check: rspec-package-tests (3.4, minimum)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: build-and-test
🔇 Additional comments (3)
lib/react_on_rails/pro_helper.rb (3)

3-8: LGTM! Clean module structure.

The module definition and warning constant are clear and well-structured, aligning with the MIT licensing approach for Pro signaling code.


11-41: Correct use of escape_javascript for XSS prevention.

The method properly escapes the dom_id before interpolating it into the JavaScript string literal, preventing potential XSS vulnerabilities. The conditional immediate hydration logic is clear and the html_safe usage is appropriate.


96-104: LGTM! Proper pluralization and defensive programming.

The method correctly handles both singular and plural cases and includes a defensive empty check. The grammatically correct message building is well-implemented.

@AbanoubGhadban AbanoubGhadban merged commit 486ab53 into master Oct 8, 2025
18 checks passed
@AbanoubGhadban AbanoubGhadban deleted the move-pro-code-to-mit-license branch October 8, 2025 16:13
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.

1 participant