This file provides guidance to WARP (warp.dev) when working with code in this repository.
React on Rails is a Ruby gem and NPM package that seamlessly integrates React components into Rails applications with server-side rendering, hot module replacement, and automatic bundle optimization. This is a dual-package project maintaining both a Ruby gem (for Rails integration) and an NPM package (for React client-side functionality).
# Initial setup for gem development
bundle && pnpm install -r
# Full setup including examples
bundle && pnpm install -r && rake shakapacker_examples:gen_all && rake node_package && rake
# Install git hooks (automatic on setup)
bundle exec lefthook install# All tests (excluding examples) - recommended for local development
rake all_but_examples
# Run specific test suites
bundle exec rspec # All Ruby tests from project root
rake run_rspec:gem # Top-level gem tests only
rake run_rspec:dummy # Dummy app tests with turbolinks
rake run_rspec:dummy_no_turbolinks # Dummy app tests without turbolinks
pnpm run test # JavaScript tests (Jest)
# Run single example test
rake run_rspec:shakapacker_examples_basic
# Test environment diagnosis
rake react_on_rails:doctor
VERBOSE=true rake react_on_rails:doctor # Detailed output# Auto-fix all violations (RECOMMENDED workflow)
rake autofix # Runs eslint --fix, prettier --write, and rubocop -A
# Manual linting
bundle exec rubocop # Ruby - MUST pass before commit
rake lint # All linters (ESLint + RuboCop)
pnpm run lint # ESLint only
rake lint:rubocop # RuboCop only
# Check formatting without fixing
pnpm start format.listDifferent# Build NPM package (TypeScript → JavaScript)
pnpm run build # One-time build
pnpm run build-watch # Watch mode for development
# Type checking
pnpm run type-checkcd react_on_rails/spec/dummy
# Start development with HMR
foreman start # Uses Procfile.dev (default)
bin/dev # Alternative
# Other modes
bin/dev static # Static assets
bin/dev prod # Production-like environment# In react_on_rails directory
pnpm run build
yalc publish
# In test app directory
yalc add react-on-rails
# After making changes (CRITICAL STEP)
cd /path/to/react_on_rails
yalc push # Push updates to all linked apps
cd /path/to/test_app
pnpm install -r # Update dependencies- Run
bundle exec rubocopand fix ALL violations - Ensure all files end with a newline character
- Use
rake autofixto auto-fix formatting issues - NEVER manually format code - let Prettier and RuboCop handle it
Note: Git hooks (via Lefthook) run automatically and check all changed files (staged + unstaged + untracked).
This project maintains two distinct but integrated packages:
- Purpose: Rails integration and server-side rendering
- Key Components:
helper.rb- Rails view helpers (react_component, etc.)server_rendering_pool.rb- Manages Node.js processes for SSRconfiguration.rb- Global configuration managementpacks_generator.rb- Auto-bundling and pack generationengine.rb- Rails engine integration- Generators in
lib/generators/react_on_rails/
- Purpose: Client-side React integration
- Key Components:
ReactOnRails.ts- Main entry point for client-side functionalityserverRenderReactComponent.ts- Server-side rendering logicclientStartup.ts- Client-side component mountingpro/- React on Rails Pro features (React Server Components, etc.)
- Rails view calls
react_componenthelper - Helper generates HTML markup with props
- Server-side rendering (if enabled) runs component in Node.js
- Client-side JavaScript hydrates/renders component in browser
- Auto-bundling system dynamically generates packs based on file structure
- Ruby: Standard gemspec-based build → published as
react_on_railsgem - JavaScript: TypeScript compilation (
node_package/src/→node_package/lib/) - Testing: RSpec for Ruby, Jest for JavaScript
- Linting: ESLint (JS/TS), RuboCop (Ruby), Prettier (formatting)
- Uses isolated Node.js processes via
connection_pool - Separate server bundles can be configured for SSR-specific code
- React Server Components (RSC) support in Pro version
- File-system-based automatic bundle generation
- Components in designated directories are auto-discovered
- Eliminates manual
javascript_pack_tagsconfiguration - See
packs_generator.rbfor implementation
- Manual:
ReactOnRails.register({ ComponentName })in pack files - Auto: Components auto-registered via
auto_load_bundle: trueoption
- Full Rails app for integration testing
- Examples of various React on Rails features
- Uses Shakapacker for webpack configuration
- Includes SSR, Redux, React Router examples
- Created via
rake shakapacker_examples:gen_all - Ignored by git
- Used for comprehensive generator testing
- Should be excluded from IDE to prevent slowdown
- Use
yalcfor local package testing, notnpm link - Always run
yalc pushafter changes to see updates in test apps - Test both with/without Shakapacker pre-installed
- Verify React components are interactive, not just rendering
- Make changes to Ruby or TypeScript code
- For NPM changes:
pnpm run buildorpnpm run build-watch - For Yalc testing:
yalc push - Run relevant tests
- Run
rake autofixto fix all linting - Commit changes
- Create failing test that reproduces issue
- Implement minimal fix
- Ensure all tests pass
- Run linting:
bundle exec rubocopandpnpm run lint - Update documentation if needed
- Plan implementation (use TODO list for complex tasks)
- Write tests first (TDD)
- Implement feature
- Test with dummy app or examples
- Run full test suite:
rake all_but_examples - Update relevant documentation
# Create test Rails app
rails new test-app --skip-javascript
cd test-app
echo 'gem "react_on_rails", path: "../react_on_rails"' >> Gemfile
bundle install
# Run generator
./bin/rails generate react_on_rails:install
# Test with yalc for full functionality
cd /path/to/react_on_rails
yalc publish
yalc push
cd /path/to/test-app
pnpm install -r
bin/devPrettier is the SOLE authority for non-Ruby files. RuboCop is the SOLE authority for Ruby files.
- Make code changes
- Run
rake autofix - Commit
- Resolve logical conflicts only (don't manually format)
git add .rake autofixgit add .git rebase --continueorgit commit
NEVER manually format during conflict resolution - this causes formatting wars.
Remove all trailing whitespace from lines
Break long lines into multiple lines using proper indentation
# Good
subject(:method_result) { instance.method_name(arg) }# rubocop:disable Security/Eval
# ... code with eval
# rubocop:enable Security/EvalExclude these directories to prevent IDE slowdowns:
/coverage,/tmp,/gen-examples/node_package/lib,/node_modules/react_on_rails/spec/dummy/app/assets/webpack/react_on_rails/spec/dummy/log,/react_on_rails/spec/dummy/node_modules,/react_on_rails/spec/dummy/tmp/spec/react_on_rails/dummy-for-generators
- ONLY use PNPM - never use npm
- Package manager enforced via
packageManagerfield in package.json
- Shakapacker >= 6.0 required (v16+ drops Webpacker support)
- Ruby >= 3.0
- Node.js >= 18 (tested: 18-22)
- Rails >= 5.2
- React Server Components (RSC)
- Streaming SSR
- Loadable Components
- Code splitting with React Router
- Requires separate Pro subscription
- Ensure yalc setup is complete
- Run
yalc pushafter changes - Check browser console for errors
- Verify component is registered correctly
- Run
rake react_on_rails:doctor - Check Shakapacker is properly installed
- Ensure package.json exists
- Test with
bin/dev killto stop conflicting processes
- Run tests from correct directory (project root vs react_on_rails/spec/dummy)
- Check that
bundle installandpnpm install -rare current - Verify git hooks are installed:
bundle exec lefthook install
- Always run
bundle exec rubocopbefore pushing - Use
rake autofixto fix most issues automatically - Check
.rubocop.ymlfor project-specific rules
The project is merging react_on_rails and react_on_rails_pro into a unified monorepo. During this transition:
- Continue contributing to current structure
- License compliance is critical (no Pro code in MIT areas)
- See
docs/MONOREPO_MERGER_PLAN_REF.mdfor details
- CONTRIBUTING.md - Comprehensive contributor guide
- AGENTS.md - AI agent instructions for working on this codebase
- CLAUDE.md - Claude Code specific guidance
- docs/ - Full documentation
- Shakapacker - Webpack integration