last update
May 23, 2026
license
MITv1.0.0
format
SKILL.md
- Install
// Downloads SKILL.md into ~/.claude/skills/remix-data-loader/
$ curl -fsSL --create-dirs -o ~/.claude/skills/remix-data-loader/SKILL.md https://claudeskil.com/skills/remix-data-loader/SKILL.md - Invoke
// Inside Claude Code, type the skill name as a slash command
> /remix-data-loader give my landing page a hero treatment - Or copy this from the README
// extracted from a Usage / Example section
$ "Scaffold a posts.$postId route that loads the post in a loader, deletes it in an action, and streams the comments list with defer."
- name:
- Remix Routes & Loaders
- slug:
- remix-data-loader
- version:
- v1.0.0
- license:
- MIT
- author:
- @chiragthummar16
- categories:
- tags:
- #remix#react-router#loaders#actions#ssr
- description:
Remix nested routes, loaders, actions, optimistic UI — the data-mutation patterns React Router 7 keeps.
// What you can do with it
- loader with typed LoaderFunctionArgs, returning data consumed via useLoaderData.
- action for POST/PUT/DELETE, paired with or useFetcher for inline mutations.
- ErrorBoundary using useRouteError and isRouteErrorResponse for thrown Response/json errors.
- Optimistic UI through useFetcher().formData and useNavigation pending states.
- Deferred/streaming data with defer(), , and resolving promises after the shell ships.
README.md
Remix Routes & Loaders
Scaffolds the data layer of a Remix (or React Router 7 framework mode) app: file-based nested routes paired with loader/action functions, error boundaries, and the optimistic-UI and streaming patterns that make Remix navigations feel instant. It's aimed at developers building server-rendered React apps who want correct data-flow wiring — Form, useFetcher, defer, <Await> — rather than hand-rolling fetch effects.
When to use it
- You're starting a new route and want the
loader+ component +ErrorBoundarystubbed in one pass. - A form mutation should update the UI before the server responds (optimistic add/delete, pending counts).
- A page has one fast query and one slow one, and you want the slow part to stream in instead of blocking the whole render.
- You're migrating Remix v2 routes to React Router 7 and want the loader/action conventions preserved.
What it does
Generates route modules that export the real Remix primitives:
loaderwith typedLoaderFunctionArgs, returning data consumed viauseLoaderData.actionforPOST/PUT/DELETE, paired with<Form method="post">oruseFetcherfor inline mutations.ErrorBoundaryusinguseRouteErrorandisRouteErrorResponsefor thrownResponse/jsonerrors.- Optimistic UI through
useFetcher().formDataanduseNavigationpending states. - Deferred/streaming data with
defer(),<Suspense>, and<Await>resolving promises after the shell ships.
It follows the flat-routes naming convention (app/routes/posts.$postId.tsx, _index.tsx) and wires meta/headers exports where relevant.
Usage
curl -fsSL --create-dirs -o ~/.claude/skills/remix-data-loader/SKILL.md https://claudeskil.com/skills/remix-data-loader/SKILL.md
"Scaffold a posts.$postId route that loads the post in a loader,
deletes it in an action, and streams the comments list with defer."
Produces, roughly:
export async function loader({ params }: LoaderFunctionArgs) {
const post = await getPost(params.postId); // awaited, blocks shell
const comments = getComments(params.postId); // promise, not awaited
return defer({ post, comments });
}
export async function action({ params }: ActionFunctionArgs) {
await deletePost(params.postId);
return redirect("/posts");
}
Tips & gotchas
- Only await what the shell needs; pass the rest as bare promises to
defer(), then wrap them in<Suspense><Await>. - Throw
json(..., { status: 404 })from a loader to render the nearestErrorBoundaryinstead of returning null and branching in JSX. - Use
useFetcher(not<Form>) for mutations that shouldn't trigger navigation — like a "mark done" toggle. - In React Router 7 framework mode, prefer the generated
Route.LoaderArgstypes over the olderLoaderFunctionArgsimport.
FAQ
Does this work with React Router 7? Yes. The loader/action/defer model carried over; the skill emits the matching imports and route-type generics for either target.
Loader vs. clientLoader? Loaders run on the server per request; the skill can add a clientLoader for client-only data or to cache across navigations.
How is form data validated? Actions read await request.formData(); the skill leaves a validation slot where you drop Zod or your own checks and return field errors for the component to render.
$ cat reviews/