Getting Started
    Core Concepts
    Building Features
    API Reference
    Deployment
    Upgrading
    Migrating
    Pro
    Advanced Topics
    Misc
    Shakacode logoShakaCodeDeveloped by

    Copyright 2020 ShakaCode

    Recommended Project Structure

    React on Rails supports two main organizational approaches for your React components.

    The current React on Rails generator creates a component-based structure optimized for automatic bundle generation:

    app/javascript/
    ├── src/
    │   ├── HelloWorld/
    │   │   ├── HelloWorld.module.css
    │   │   └── ror_components/          # Auto-discovered by React on Rails
    │   │       ├── HelloWorld.jsx       # Client & server rendering
    │   │       └── HelloWorld.server.js # Optional: server-only code
    │   └── AnotherComponent/
    │       └── ror_components/
    │           ├── AnotherComponent.client.jsx  # Client-only rendering
    │           └── AnotherComponent.server.jsx  # Server-only rendering
    └── packs/
        ├── generated/                   # Auto-generated entry points (gitignored)
        │   ├── HelloWorld.js
        │   └── AnotherComponent.js
        └── server-bundle.js             # Server rendering entry point

    Key features:

    • Components in ror_components/ directories are automatically discovered and registered
    • Each component gets its own webpack bundle for optimal code splitting
    • No manual ReactOnRails.register() calls needed
    • Supports separate .client.jsx and .server.jsx files for different rendering logic

    For details, see Auto-Bundling Guide and Generator Details.

    Traditional Manual Structure (Legacy)

    For projects requiring explicit control over webpack entry points:

    app/javascript/
    ├── bundles/
    │   └── HelloWorld/
    │       ├── components/
    │       │   └── HelloWorld.jsx
    │       └── startup/
    │           └── registration.js      # Manual ReactOnRails.register()
    └── packs/
        └── hello-world-bundle.js        # Webpack entry point

    This approach requires manual component registration and webpack configuration but offers complete control over bundling strategy.

    Choosing Your Structure

    Use modern auto-bundling if:

    • Starting a new project
    • Want automatic code splitting per component
    • Prefer convention over configuration
    • Want to minimize boilerplate

    Use traditional manual structure if:

    • Have complex custom webpack requirements
    • Need fine-grained control over bundle composition
    • Migrating from older React on Rails versions

    For most projects, we recommend the modern auto-bundling approach.

    Steps to convert from the generator defaults to use a /client directory for source code

    1. Move the directory:
    mv app/javascript client
    1. Edit your /config/shakapacker.yml file. Change the default/source_path:
    source_path: client

    Styling Your Components

    React on Rails supports multiple approaches for styling your components. The modern recommended approach uses CSS Modules with co-located stylesheets.

    The generator creates components with CSS Module support out of the box:

    app/javascript/src/HelloWorld/
    ├── ror_components/
    │   ├── HelloWorld.client.jsx
    │   └── HelloWorld.module.css    # Co-located with component

    Example usage:

    import React from 'react';
    import * as style from './HelloWorld.module.css';
    
    const HelloWorld = () => <label className={style.bright}>Hello World</label>;

    Benefits:

    • Scoped styles: Class names are automatically scoped to prevent conflicts
    • Co-location: Styles live next to their components for better organization
    • Type safety: Works seamlessly with TypeScript
    • Hot reloading: Style changes reload instantly without page refresh
    • Zero configuration: Works out of the box with the generator

    Alternative: Rails Asset Pipeline

    You can continue using Rails' traditional asset pipeline with sass-rails or similar gems:

    <%# app/views/layouts/application.html.erb %>
    <%= stylesheet_link_tag 'application', media: 'all' %>

    Use this approach when:

    • You have existing Rails stylesheets you want to keep
    • You prefer keeping styles completely separate from JavaScript
    • You don't need component-scoped styling

    Advanced: Global Styles with Webpack

    For global styles (fonts, resets, variables), you can create additional webpack entry points:

    app/javascript/
    ├── packs/
    │   ├── application.css    # Global styles
    │   └── server-bundle.js
    └── src/
        └── HelloWorld/
            └── ror_components/
                ├── HelloWorld.jsx
                └── HelloWorld.module.css

    Import global styles in your layout:

    <%= stylesheet_pack_tag 'application' %>