Skip to content

Monorepo of pro and basic #1765

@justin808

Description

@justin808

Complete GitHub Issue: Monorepo of Pro and Basic #1765

Original Proposal by Justin Gordon (@justin808)

Created: September 7, 2025
Assignees: @AbanoubGhadban @ihabadham

Initial Vision

Merging react_on_rails and react_on_rails_pro into a single monorepo to:

  • Simplify development workflow
  • Unify documentation and examples
  • Maintain separate packages while sharing infrastructure
  • Open source the Pro codebase with subscription licensing for production use

Original Implementation Steps Proposed:

  1. Import Pro repository as a squashed commit
  2. Add SPDX license headers to source files
  3. Update documentation and links
  4. Archive old Pro repository
  5. Create unified development workflow

Original Git Commands Suggested:

# Clone and prepare repositories
git clone git@github.com:shakacode/react_on_rails.git
git clone git@github.com:shakacode/react_on_rails_pro.git

# Bring Pro in as single squashed commit
cd react_on_rails
git remote add pro ../react_on_rails_pro
git fetch pro
git merge --squash --no-commit pro/main

Updated & Refined Implementation Plan by @AbanoubGhadban

Based on extensive analysis and planning, we've refined the approach to ensure CI safety, proper git history preservation, and strict license compliance throughout the merger process.

Final Repository Structure

react_on_rails/ (monorepo root)
├── lib/
│   ├── react_on_rails/           # Core Ruby (MIT)
│   └── react_on_rails_pro/       # Pro Ruby (Pro license)
├── packages/                     # NPM packages (yarn workspace)
│   ├── react-on-rails/           # Core JS/TS (MIT)
│   ├── react-on-rails-pro/       # Pro JS/TS (Pro license)
│   └── react-on-rails-pro-node-renderer/  # Pro node renderer
├── spec/
│   ├── ruby/                     # Ruby specs
│   └── packages/                 # JS specs
├── react_on_rails.gemspec        # Core gem
├── react_on_rails_pro.gemspec    # Pro gem  
├── package.json                  # Workspace manager
├── Gemfile                       # Both gems
└── README.md

Final Package Output

Ruby Gems (2 separate):

  • react_on_rails gem (MIT License)
  • react_on_rails_pro gem (Pro License, depends on react_on_rails)

NPM Packages (3 separate):

  • react-on-rails (MIT License)
  • react-on-rails-pro (Pro License, depends on react-on-rails)
  • react-on-rails-pro-node-renderer (Pro License)

Implementation Plan - Detailed PRs with License Compliance

Phase 1: Pre-Merger Preparation

PR #1: License Cleanup & Documentation

Branch: prepare-licenses
Target: Both repositories (separate PRs)

Tasks:

  • Update react_on_rails_pro/LICENSE to reference v2.0 license consistently
  • Add migration documentation in MERGER_PLAN.md
  • Update CONTRIBUTING.md to mention upcoming merger
  • Create FAQ.md about licensing post-merger

🔒 License Compliance:

  • Verify all pro files have proper license headers
  • Ensure license file references are correct
  • Document which directories will be under which license

Success Criteria: ✅ All existing CI checks pass + License compliance verified

💡 Developer Tip: Double-check that all pro files have appropriate license headers and that license documentation accurately reflects current directory structure.


Phase 2: Git Subtree Merger (Keep Original Structure)

PR #2: Merge react_on_rails_pro via Git Subtree + Fix CI

Branch: merge-pro-subtree-with-ci
Target: react_on_rails repository

Git Strategy: Using git subtree (preserves history, unlike original squash proposal)

# Add react_on_rails_pro as remote
git remote add pro-origin https://github.com/shakacode/react_on_rails_pro.git
git fetch pro-origin

# Merge using subtree (preserves history)
git subtree add --prefix=react_on_rails_pro pro-origin/main --squash

Tasks:

  • Execute git subtree merge into react_on_rails_pro/ directory
  • CRITICAL: Update CI to run tests for both packages
  • Keep GitHub Actions for core package tests
  • Keep CircleCI for pro package tests (temporarily)
  • Update root scripts to test both packages
  • Ensure both packages build independently

Directory Structure After Merge:

react_on_rails/ (root)
├── lib/react_on_rails/              # Original core
├── node_package/                    # Original core JS  
├── spec/                            # Original core tests
├── react_on_rails.gemspec           # Original core
├── package.json                     # Original core
├── .github/workflows/               # UPDATED - tests core
│
├── react_on_rails_pro/             # ADDED - Complete pro repo
│   ├── lib/react_on_rails_pro/
│   ├── packages/node-renderer/  
│   ├── spec/
│   ├── react_on_rails_pro.gemspec
│   ├── package.json
│   └── .circleci/                   # Keep temporarily

🔒 License Compliance:

  • Update root LICENSE.md to explicitly list pro directories:
    ## React on Rails Pro License applies to:
    - `react_on_rails_pro/` (entire directory)
  • Verify all pro files remain under react_on_rails_pro/ directory
  • Ensure no pro code accidentally gets MIT license

Success Criteria:ALL CI jobs pass for both core and pro packages independently

💡 Developer Tip: After the subtree merge, ensure that the entire react_on_rails_pro/ directory is listed in LICENSE.md as Pro-licensed. Verify no pro files accidentally ended up in MIT-licensed directories during the merge.


Phase 3: Pre-Monorepo Structure Preparation

PR #3: Prepare Core Package for Workspace Structure

Branch: prepare-core-workspace

Tasks:

  • Create packages/react-on-rails/ directory
  • Move node_package/src/ to packages/react-on-rails/src/
  • Create packages/react-on-rails/package.json
  • Update root package.json to workspace manager
  • Update build scripts and import paths
  • Keep react_on_rails_pro/ unchanged

🔒 License Compliance:

  • Verify NO pro files moved to MIT-licensed core package
  • Ensure packages/react-on-rails/src/ contains ONLY MIT-licensed code
  • Update LICENSE.md if paths change:
    ## MIT License applies to:
    - `packages/react-on-rails/` (new path)

Success Criteria: ✅ All CI checks pass + No pro code in MIT directories

💡 Developer Tip: When moving core files to packages/react-on-rails/, carefully verify that no pro files (especially from node_package/src/pro/) accidentally get moved to the MIT-licensed directory. Update LICENSE.md to reflect the new packages/react-on-rails/ path.


PR #4: Prepare Pro Package for Workspace Structure

Branch: prepare-pro-workspace

Tasks:

  • Move react_on_rails_pro/packages/node-renderer/ to packages/react-on-rails-pro-node-renderer/
  • Extract pro JS features to packages/react-on-rails-pro/src/
  • Create individual package.json files for pro packages
  • Update workspace to include all 3 NPM packages
  • Update CI to test all packages

🔒 License Compliance:

  • Critical: Update LICENSE.md for new pro directory paths:
    ## React on Rails Pro License applies to:
    - `packages/react-on-rails-pro/` (NEW)
    - `packages/react-on-rails-pro-node-renderer/` (NEW)
    - `react_on_rails_pro/` (remaining files)
  • Add Pro license headers to moved files
  • Verify all pro packages have "license": "UNLICENSED" in package.json

Success Criteria: ✅ All CI checks pass + All pro files properly licensed + License paths updated

💡 Developer Tip: This is a critical step for license compliance! When creating new pro directories (packages/react-on-rails-pro/ and packages/react-on-rails-pro-node-renderer/), immediately update LICENSE.md to include these new paths. Ensure all moved pro files retain their Pro license headers and that the new package.json files have "license": "UNLICENSED".


Phase 4: Final Monorepo Restructuring

PR #5: Restructure Ruby Gems to Final Layout

Branch: restructure-ruby-gems

Tasks:

  • Move react_on_rails_pro/lib/react_on_rails_pro/ to lib/react_on_rails_pro/
  • Move react_on_rails_pro/react_on_rails_pro.gemspec to root
  • Move all Ruby specs to spec/ruby/
  • Update root Gemfile to include both gemspecs
  • Remove empty react_on_rails_pro/ directory

🔒 License Compliance:

  • Update LICENSE.md to final directory structure:
    ## React on Rails Pro License applies to:
    - `lib/react_on_rails_pro/`
    - `packages/react-on-rails-pro/`
    - `packages/react-on-rails-pro-node-renderer/`
    - `spec/ruby/react_on_rails_pro/`
  • Update both gemspec files with correct license:
    # react_on_rails.gemspec
    s.license = "MIT"
    
    # react_on_rails_pro.gemspec  
    s.license = "UNLICENSED"  # Pro license
  • Verify no pro files accidentally moved to MIT directories

Success Criteria: ✅ All CI checks pass + Final license structure verified

💡 Developer Tip: This step finalizes the directory structure, so it's crucial to update LICENSE.md with all final pro paths. When moving react_on_rails_pro/lib/react_on_rails_pro/ to lib/react_on_rails_pro/, ensure you update the LICENSE.md path from the temporary location to the final location. Double-check that pro specs moved to spec/ruby/react_on_rails_pro/ and not spec/ruby/react_on_rails/.


Phase 5: CI/CD & Tooling Unification

PR #6: Unify CI/CD Configuration

Branch: unify-cicd

Tasks:

  • DECISION POINT: Choose final CI system
    • Option A: Migrate everything to GitHub Actions
    • Option B: Migrate everything to CircleCI
    • Option C: Hybrid approach (GitHub Actions + CircleCI for specific features)
  • Implement chosen CI strategy
  • Remove duplicate CI configurations
  • Update build and release scripts
  • Add independent package release workflows

🔒 License Compliance:

  • Add automated license checking to CI pipeline:
    license-check:
      runs-on: ubuntu-latest
      steps:
        - name: Verify Pro License Headers
          run: |
            find lib/react_on_rails_pro packages/react-on-rails-pro* -name "*.rb" -o -name "*.js" -o -name "*.ts" | \
            xargs grep -L "Pro License\|UNLICENSED" && exit 1 || echo "✅ All pro files properly licensed"
  • Add license verification to release process
  • Ensure CI fails if pro files missing license headers

Success Criteria: ✅ All CI checks pass + Automated license enforcement in place

💡 Developer Tip: When consolidating CI configurations, ensure that any new build scripts or release processes respect the license boundaries. If you create any new directories during CI setup, verify they're properly classified as MIT or Pro in LICENSE.md.


Phase 6: Documentation & Polish

PR #7: Update Documentation & Examples

Branch: update-docs-examples

Tasks:

  • Update main README.md for monorepo
  • Create individual READMEs for each package
  • Create migration guide for existing users
  • Update installation instructions
  • Update example applications
  • Update changelog and release notes

🔒 License Compliance:

  • Document licensing clearly in README.md:
    ## 📄 Licensing
    
    This monorepo contains packages under different licenses:
    
    ### MIT Licensed (Free & Open Source):
    - `react_on_rails` Ruby gem
    - `react-on-rails` NPM package
    - Core functionality in `lib/react_on_rails/` and `packages/react-on-rails/`
    
    ### Pro Licensed (Subscription Required for Production):
    - `react_on_rails_pro` Ruby gem
    - `react-on-rails-pro` NPM package  
    - `react-on-rails-pro-node-renderer` NPM package
    - Pro functionality in `lib/react_on_rails_pro/` and `packages/react-on-rails-pro*/`
  • Update package READMEs with appropriate license info
  • Verify all examples respect license boundaries

Success Criteria: ✅ All CI checks pass + License documentation complete and accurate

💡 Developer Tip: When updating documentation and examples, ensure that any new example files or documentation directories are properly placed. If examples use pro features, make sure they're clearly marked and that any example code respects the license boundaries. Update the main README.md to accurately list all current pro directory paths.


Key Improvements Over Original Plan

1. CI Safety First

  • Every PR must pass CI before proceeding (addressing concern about CI integrity)
  • No phases that skip CI validation
  • Early detection of breaking changes

2. Git History Preservation

  • Using git subtree instead of squashed commit (preserves contributor history)
  • Maintains contributor attribution
  • Preserves commit history and relationships

3. Gradual Migration with License Compliance

  • Intermediate working states at each step
  • Dual CI during transition (GitHub Actions + CircleCI)
  • Strict license compliance checks at every step
  • Always have rollback capability

4. Package Independence

  • Maintains separate package identity
  • Independent versioning and releases
  • Clear licensing boundaries (MIT vs Pro)

License Enforcement Tools

Automated License Checker Script

Create script/check-license-compliance.rb:

#!/usr/bin/env ruby
# Script to verify license compliance across the monorepo

PRO_DIRECTORIES = %w[
  lib/react_on_rails_pro
  packages/react-on-rails-pro
  packages/react-on-rails-pro-node-renderer
  spec/ruby/react_on_rails_pro
].freeze

def check_pro_license_headers
  puts "🔍 Checking pro files have correct license headers..."
  PRO_DIRECTORIES.each do |dir|
    next unless Dir.exist?(dir)
    
    files = Dir.glob("#{dir}/**/*.{rb,js,ts,tsx}")
    files.each do |file|
      content = File.read(file)
      unless content.match?(/Pro License|UNLICENSED|React on Rails Pro/i)
        puts "⚠️  WARNING: Pro file missing license header: #{file}"
      end
    end
  end
  puts "✅ Pro license headers verified"
end

check_pro_license_headers
puts "🎉 License compliance check passed!"

Key License Compliance Rules

  1. Always Update LICENSE.md When Moving Pro Directories:

    • If you rename or move any pro directory, immediately update LICENSE.md
    • Ensure the license file accurately reflects the current structure
  2. Verify Directory Classification:

    • MIT directories: lib/react_on_rails/, packages/react-on-rails/, core specs
    • Pro directories: All paths explicitly listed in LICENSE.md under "React on Rails Pro License"
  3. Double-Check After Each Move:

    • After moving files, verify no pro code ended up in MIT directories
    • After creating new directories, classify them in LICENSE.md immediately

Timeline & Resources

Estimated Duration: 4-5 weeks
Assignees: @AbanoubGhadban @ihabadham
Review Requirements: Each PR requires CI ✅ + code review approval

Success Metrics

  • All existing functionality preserved
  • No breaking changes for users
  • All CI checks pass throughout process
  • Both gems and all NPM packages build independently
  • Documentation updated and migration guide available
  • License compliance verified at every step
  • Community can contribute to unified repo
  • Git history preserved from both repositories

Context for AI Agents

This issue serves as the complete context for implementing the react_on_rails monorepo merger. Any AI agent working on this plan should:

  1. Follow the PR sequence exactly - each builds on the previous
  2. Ensure CI passes at every step - this is non-negotiable
  3. Maintain strict license compliance - update LICENSE.md whenever pro directories change
  4. Preserve package independence - we're creating a monorepo, not merging packages
  5. Document all changes - update READMEs, migration guides, and examples
  6. Preserve git history - use subtree merge, not squashed commits

The plan balances the benefits of a monorepo (shared tooling, unified development) with the need for separate packages (independent licensing, versioning, and distribution) while ensuring strict license compliance throughout the process.

⚠️ Important: License compliance is critical - always verify that LICENSE.md accurately reflects the current directory structure after any file moves or restructuring.


Next Steps:

  1. Review and approve this updated plan
  2. Begin with PR TODO for first version #1: License cleanup in both repositories
  3. Proceed through each phase with CI validation and license compliance
  4. Make final CI system decision at Phase 5

Metadata

Metadata

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions