Form handling with React Hook Form

React Hook Form provides performant form handling with minimal re-renders. Unlike controlled components that re-render on every keystroke, it uses uncontrolled inputs with refs. The register function connects inputs to the form state, and handleSubmit

React Router with protected routes

React Router v6 provides declarative routing with data loading and authentication guards. I wrap protected routes in a ProtectedRoute component that checks authentication state from context and redirects to login if needed. The Navigate component hand

Context API for global UI state

While React Query handles server state, I use Context API for client-side UI state like theme, sidebar visibility, or current user. Each context lives in its own file with a custom hook for consuming it. The context provider wraps the app at a high le

TypeScript types from Rails serializers

Keeping TypeScript types in sync with Rails API responses is critical but tedious. I generate TypeScript interfaces automatically from Rails serializers or JSON Schema using tools like quicktype or custom scripts. For manual definitions, I create a ty

React Query for server state management

React Query eliminates boilerplate for fetching, caching, and syncing server data. Instead of managing loading/error/data states manually with useState, I define queries with useQuery that handle caching, background refetching, and stale data automati

Axios API client with interceptors

A centralized API client provides a single place to configure authentication, error handling, and request/response transformations. I use axios for its interceptor support and automatic JSON transformation. Request interceptors attach the JWT token fr

React app structure with Vite and TypeScript

Vite provides lightning-fast dev server startup and hot module replacement compared to Create React App. I scaffold React projects with TypeScript for type safety across the entire frontend. The folder structure separates concerns: components for reus

Rails API-only app setup for React frontend

When building a React SPA, I configure Rails in API-only mode to skip view rendering, asset pipeline, and session cookies. The --api flag generates a lean Rails app focused on JSON responses. I enable CORS to allow the React dev server on localhost:51

Hotwire-powered multi-step forms

Multi-step forms traditionally require complex JavaScript state management, but Hotwire makes them simple. Each step is a separate controller action that renders a Turbo Frame containing the current step's fields. Navigation between steps updates only

Tailwind CSS with Rails asset pipeline

Tailwind CSS provides utility-first styling that pairs perfectly with Rails component-driven architecture. I configure Tailwind to scan templates for class names and generate only the CSS being used. The standalone CLI runs during development with --w

Toast notifications with Stimulus and Tailwind

Toast notifications provide non-intrusive feedback for user actions. I build a notification system with Stimulus that manages a stack of toasts, auto-dismisses them after a timeout, and supports manual dismissal. Notifications are queued when multiple

Progress indicators for long-running operations

Users need feedback during slow operations like file uploads or complex processing. I combine Turbo Streams with background jobs to show real-time progress. When an operation starts, I enqueue a job that periodically broadcasts progress updates via Ac