This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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.
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 scanningControllers 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').
Two separate directories serve different purposes:
app/javascript/— Vite source: entrypoints, page components (pages/), Stimulus controllersapp/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.
app/javascript/entrypoints/inertia.ts— React app mount point, page resolutionapp/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 entrypointconfig/initializers/inertia_rails.rb— Inertia config (encrypted history, auto-include errors hash)config/routes.rb— All routes; root ispages#homecomponents.json— shadcn/ui config for component generation
- Add route in
config/routes.rb - Create controller action that calls
render inertia: 'PageName', props: { ... } - Create
app/javascript/pages/PageName.tsxReact component
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.
- Ruby:
rubocop-rails-omakasestyle,frozen_string_literal: truepragma - Tailwind CSS 4
@theme inlinesyntax with CSS custom properties for theming ApplicationControllerrestricts to modern browsers only- Inertia always includes the errors hash in props for form validation
- SQLite databases stored in
storage/directory