Skip to content

Latest commit

 

History

History
68 lines (48 loc) · 3.15 KB

File metadata and controls

68 lines (48 loc) · 3.15 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Tech Stack

Rails 8 + React 19 + SQLite app template using Inertia.js as the bridge (no separate API layer). TypeScript 5.9, Tailwind CSS 4, shadcn/ui (new-york style), Vite 7 bundler, Propshaft asset pipeline. Ruby 3.2.0.

Background jobs, caching, and WebSockets use the Rails 8 "Solid" trifecta (Solid Queue, Solid Cache, Solid Cable) — all database-backed, no Redis.

Commands

bin/setup              # Initial setup (bundle, db:prepare, start dev)
bin/dev                # Start dev server (Rails on :3000 + Vite on :3036)
bin/rails test         # Run unit/integration tests (Minitest)
bin/rails test:system  # System tests (Capybara + headless Chrome)
bin/rails test test/models/user_test.rb           # Single test file
bin/rails test test/models/user_test.rb:42        # Single test by line
npm run check          # TypeScript type checking
bin/rubocop            # Ruby linting (rubocop-rails-omakase style)
bin/brakeman           # Security scanning

Architecture

Inertia.js Pattern (no API routes)

Controllers render Inertia responses instead of ERB views:

render inertia: 'Home', props: { items: @items }

Inertia resolves the page name to a React component in app/javascript/pages/. The mapping is in app/javascript/entrypoints/inertia.ts using import.meta.glob('../pages/**/*.tsx').

Frontend Directory Structure

Two separate directories serve different purposes:

  • app/javascript/ — Vite source: entrypoints, page components (pages/), Stimulus controllers
  • app/frontend/ — Shared React code: shadcn/ui components (components/ui/), utilities (lib/)

The @ path alias resolves to app/frontend/ in both Vite and TypeScript configs. Import shared components as @/components/ui/button, utilities as @/lib/utils.

Key Files

  • app/javascript/entrypoints/inertia.ts — React app mount point, page resolution
  • app/javascript/entrypoints/application.css — Tailwind CSS 4 theme with CSS variable system (light/dark mode)
  • app/views/layouts/application.html.erb — Loads Vite client, React refresh, and Inertia entrypoint
  • config/initializers/inertia_rails.rb — Inertia config (encrypted history, auto-include errors hash)
  • config/routes.rb — All routes; root is pages#home
  • components.json — shadcn/ui config for component generation

Adding a New Page

  1. Add route in config/routes.rb
  2. Create controller action that calls render inertia: 'PageName', props: { ... }
  3. Create app/javascript/pages/PageName.tsx React component

Dual Asset Systems

The app has both importmap-rails (Turbo/Stimulus in app/javascript/controllers/) and Vite (React/Inertia). The primary frontend is the Vite/React/Inertia pipeline.

Conventions

  • Ruby: rubocop-rails-omakase style, frozen_string_literal: true pragma
  • Tailwind CSS 4 @theme inline syntax with CSS custom properties for theming
  • ApplicationController restricts to modern browsers only
  • Inertia always includes the errors hash in props for form validation
  • SQLite databases stored in storage/ directory