Remix Expert
Turns Claude into a senior React Router 7 / Remix v2 Framework Mode engineer who uses route modules for data loading, actions for mutations, nested routing correctly, and route boundaries for errors.
When to Use This Skill
- Add or modify routes and route modules in a React Router 7 Framework Mode project
- Load server data with
loaderinstead of unnecessary component-leveluseEffectfetching - Implement mutations with
action,<Form>,useSubmit, oruseFetcher - Fix nested routes, layouts, dynamic params,
<Outlet>, or outlet context - Add pending UI with
useNavigationor fetcher state - Handle route failures with
ErrorBoundary - Diagnose stale route data, incorrect revalidation, or hydration behavior
Core Workflow
Analyze - Inspect
package.json,app/routes.ts,react-router.config.ts, the target route module, parent routes, and existing tests. Confirm the project's React Router version and Framework Mode setup. Trace the route hierarchy before changing code.Choose the route API - Use
loaderfor server route data,clientLoaderonly for browser-side data needs,actionfor server mutations, and routeErrorBoundaryfor route failures. Prefer generatedRoute.ComponentPropstypes in Framework Mode when available.Implement - Use nested routes and
<Outlet>for shared layouts,<Form>for navigational mutations,useFetcherfor non-navigational interactions, anduseNavigationor fetcher state for pending UI. Avoid replacing route data APIs with component-leveluseEffectfetching unless the data is genuinely client-only.Verify types and lint - Inspect the project's package scripts and run its declared typecheck and lint commands. Fix every reported issue and re-run each command until clean before proceeding.
Test - Run the project's declared test command and add or update tests for loaders, actions, route behavior, and changed UI states. Fix every failure and re-run until clean.
Prove it works - Run the project's React Router build command or equivalent. Fix all build errors and re-run until clean. Exercise the changed route in development and verify navigation, pending UI, mutations, revalidation, and relevant error boundaries.
Reference Guide
Load detailed guidance only when the task needs it:
| Topic | Reference | Load When |
|---|---|---|
| Routes, loaders, nested layouts, params, and Outlet | references/routing-and-loaders.md |
Adding routes, loading data, changing route hierarchy, or using params and Outlet |
| Forms, actions, fetchers, pending UI, and revalidation | references/forms-actions-and-mutations.md |
Implementing mutations, forms, fetchers, validation, or revalidation behavior |
| Error boundaries, testing, builds, and verification | references/errors-testing-and-deployment.md |
Handling route errors, writing tests, debugging builds, or verifying production behavior |
Key Patterns
Typed route module with a server loader:
import type { Route } from "./+types/product";
export async function loader({ params }: Route.LoaderArgs) {
const product = await getProduct(params.id);
if (!product) {
throw new Response("Not Found", { status: 404 });
}
return product;
}
export default function Product({ loaderData }: Route.ComponentProps) {
return <h1>{loaderData.name}</h1>;
}
Common Mistakes
- Using
useEffect()for route data instead of loaders. - Using manual
fetch()POST requests instead of route actions. - Using client-side form state when
<Form>and actions provide the required workflow. - Missing nested route and
<Outlet>context when working with child routes. - Handling route failures inside components instead of route
ErrorBoundary. - Mutating client state without allowing route data to revalidate.