agents-inc/skills/src/skills/web-meta-framework-remix/SKILL.md
web-meta-framework-remix
File-based routing, loaders, actions, defer streaming, useFetcher, error boundaries, progressive enhancement
- Source repository stars
- 23
- Declared platforms
- 0
- Static risk flags
- 1
- Last source update
- 2026-08-09
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
Quick Guide: Each route exports a loader for reads and an action for writes. Both run on the server. Data flows through loaders, mutations go through actions, forms work without JavaScript, and nested routes enable parallel data loading. json() and defer() are deprecated in Reac…
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/agents-inc/skills --skill "src/skills/web-meta-framework-remix"Inspect the Agent Skill "web-meta-framework-remix" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/web-meta-framework-remix/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
IMPORTANT: React Router v7 Migration
Remix has merged into React Router v7. What was planned as Remix v3 is now React Router v7 "framework mode".
Remix has merged into React Router v7. What was planned as Remix v3 is now React Router v7 "framework mode".This skill covers both Remix v2 and React Router v7 patterns. Examples use Remix v2 imports by default with RR v7 equivalents documented in examples/react-router-v7.md.Migration guide: Upgrading from Remix - 02
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)
Building full-stack React applications with server-side renderingImplementing data loading with loaders and mutations with actionsCreating progressively enhanced forms that work without JavaScript - 03
Philosophy
Remix simplifies full-stack development to a single mental model: each route exports a loader for reads and an action for writes. Both functions execute exclusively on the server, enabling direct database access without exposing secrets to the client.
Server-first data loading: Loaders run on the server before rendering, eliminating client-side data fetching waterfallsProgressive enhancement: Forms work with plain POST requests -- JavaScript enhances but isn't requiredHTTP semantics: Caching uses standard HTTP headers (Cache-Control), not framework-specific solutions - 04
Core Patterns
Files in app/routes/ become URL paths. File naming conventions control nesting, layouts, and dynamic segments.
Always throw Response for expected errors (triggers ErrorBoundary)Use useLoaderData() for type-safe access (or Route.ComponentProps in RR v7)Loaders run on every navigation -- parent loaders re-run even for child route changes - 05
Pattern 1: File-Based Routing
Files in app/routes/ become URL paths. File naming conventions control nesting, layouts, and dynamic segments.
Files in app/routes/ become URL paths. File naming conventions control nesting, layouts, and dynamic segments.Why good: File names map directly to URLs, $ prefix for dynamic segments, loader params are typed, named constant for status codeSee examples/core.md for complete route examples and examples/nested-routes.md for layout nesting patterns.
Permission review
Static risk signals and limitations
Network access
The documentation includes network, browsing, or remote request actions.
**Web standards**: Uses Fetch API Request/Response objects throughoutEvidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 94/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- agents-inc/skills
- Skill path
- src/skills/web-meta-framework-remix/SKILL.md
- Commit
- 81d43a51211aca12c85dcc16085fa99014ec548e
- License
- MIT
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
Remix / React Router v7 Framework Patterns
Quick Guide: Each route exports a
loaderfor reads and anactionfor writes. Both run on the server. Data flows through loaders, mutations go through actions, forms work without JavaScript, and nested routes enable parallel data loading.json()anddefer()are deprecated in React Router v7 -- return raw objects instead, usedata()for custom headers/status.
<migration_notice>
IMPORTANT: React Router v7 Migration
Remix has merged into React Router v7. What was planned as Remix v3 is now React Router v7 "framework mode".
| Remix v2 (Deprecated) | React Router v7 (Current) |
|---|---|
json(data) | Return raw objects directly |
json(data, { status, headers }) | data(data, { status, headers }) |
defer({ key: promise }) | Return { key: promise } with Single Fetch |
@remix-run/node imports | react-router / @react-router/node |
LoaderFunctionArgs | Route.LoaderArgs (generated types) |
ActionFunctionArgs | Route.ActionArgs (generated types) |
useLoaderData<typeof loader>() | loaderData prop via Route.ComponentProps |
RemixServer | ServerRouter (from react-router) |
RemixBrowser | HydratedRouter (from react-router/dom) |
| File-based routing (automatic) | routes.ts + optional @react-router/fs-routes |
This skill covers both Remix v2 and React Router v7 patterns. Examples use Remix v2 imports by default with RR v7 equivalents documented in examples/react-router-v7.md.
Migration guide: Upgrading from Remix
</migration_notice>
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST export loaders and actions as named exports from route modules only -- they do not work in non-route files)
(You MUST throw Response objects for expected errors (404, 403) -- use ErrorBoundary for handling)
(You MUST await critical data and return non-critical data as Promises for streaming)
(You MUST use named constants for HTTP status codes -- no magic numbers)
</critical_requirements>
Auto-detection: Remix routes, React Router v7, loader function, action function, clientAction, clientLoader, useLoaderData, useActionData, useFetcher, defer, ErrorBoundary, Form component, meta function, links function, Single Fetch, ServerRouter, HydratedRouter, Route.LoaderArgs, Route.ComponentProps, shouldRevalidate
When to use:
- Building full-stack React applications with server-side rendering
- Implementing data loading with loaders and mutations with actions
- Creating progressively enhanced forms that work without JavaScript
- Streaming non-critical data with defer/Promises and Suspense
- Handling errors gracefully with route-level ErrorBoundary
When NOT to use:
- Static sites without server-side logic
- Simple SPAs without server rendering needs
- Projects already committed to a different meta-framework
Key patterns covered:
- File-based routing (routes/, _index, $params, _layout)
- Loaders for server-side data fetching
- Actions for mutations with progressive enhancement
- Streaming with defer() / raw Promises (RR v7)
- useFetcher for non-navigation mutations and optimistic UI
- Error boundaries with multi-status handling
- Meta and Links functions for SEO
- Resource routes (API endpoints, file downloads)
- Nested routing with parallel data loading
- React Router v7 migration (Single Fetch, type generation, clientAction)
Philosophy
Remix simplifies full-stack development to a single mental model: each route exports a loader for reads and an action for writes. Both functions execute exclusively on the server, enabling direct database access without exposing secrets to the client.
Core Principles:
- Server-first data loading: Loaders run on the server before rendering, eliminating client-side data fetching waterfalls
- Progressive enhancement: Forms work with plain POST requests -- JavaScript enhances but isn't required
- HTTP semantics: Caching uses standard HTTP headers (Cache-Control), not framework-specific solutions
- Nested routes: URL segments map to component hierarchy, enabling parallel data loading
- Web standards: Uses Fetch API Request/Response objects throughout
Data Flow:
URL Change -> Loader(s) Execute -> Component Renders -> User Interacts
|
Action Executes -> Loaders Revalidate
Core Patterns
Pattern 1: File-Based Routing
Files in app/routes/ become URL paths. File naming conventions control nesting, layouts, and dynamic segments.
| File Name | URL | Description |
|---|---|---|
_index.tsx | / | Index route (root) |
about.tsx | /about | Static route |
blog.$slug.tsx | /blog/:slug | Dynamic parameter |
blog_.tsx | /blog | Pathless layout escape |
_auth.tsx | (none) | Layout route (no URL segment) |
_auth.login.tsx | /login | Route nested in layout |
$.tsx | /* | Splat/catch-all route |
// app/routes/blog.$slug.tsx -- dynamic route with loader
import type { LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
const HTTP_NOT_FOUND = 404;
export async function loader({ params }: LoaderFunctionArgs) {
const post = await db.post.findUnique({ where: { slug: params.slug } });
if (!post) throw new Response("Not Found", { status: HTTP_NOT_FOUND });
return { post };
}
Why good: File names map directly to URLs, $ prefix for dynamic segments, loader params are typed, named constant for status code
See examples/core.md for complete route examples and examples/nested-routes.md for layout nesting patterns.
Pattern 2: Loaders for Data Fetching
Loaders are server-only functions that provide data to routes. They run on initial server render and on client navigation via fetch.
const HTTP_NOT_FOUND = 404;
export async function loader({ params, request }: LoaderFunctionArgs) {
const user = await db.user.findUnique({ where: { id: params.userId } });
if (!user) {
throw json({ message: "User not found" }, { status: HTTP_NOT_FOUND });
}
return json({ user });
}
Key rules:
- Always throw Response for expected errors (triggers ErrorBoundary)
- Use
useLoaderData<typeof loader>()for type-safe access (orRoute.ComponentPropsin RR v7) - Loaders run on every navigation -- parent loaders re-run even for child route changes
- Use
shouldRevalidateto optimize unnecessary re-runs
See examples/loaders.md for authentication, pagination, and caching examples.
Pattern 3: Actions for Mutations
Actions handle non-GET requests (POST, PUT, DELETE, PATCH). They run before loaders and enable progressive form handling.
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const intent = formData.get("intent");
switch (intent) {
case "update": {
/* ... */ return json({ success: true });
}
case "delete": {
/* ... */ return redirect("/items");
}
default:
throw new Error(`Unknown intent: ${intent}`);
}
}
Key rules:
- Use hidden
intentfield for multiple actions in one route - Redirect after successful mutations to prevent double-submission
- Return validation errors with
json({ errors }, { status: 400 }) - Forms work without JavaScript -- progressive enhancement by default
See examples/actions.md for validation and examples/forms.md for multi-form patterns.
Pattern 4: Streaming with defer / Promises
Await critical data, return Promises for non-critical data that can stream in.
// Remix v2: use defer()
return defer({
user, // Awaited -- critical
analytics: getAnalytics(), // Promise -- streams in
});
// React Router v7: return raw objects with Promises
return {
user, // Awaited -- critical
analytics: getAnalytics(), // Promise -- streams via Single Fetch
};
Render streamed data with <Suspense> + <Await>:
<Suspense fallback={<Skeleton />}>
<Await resolve={analytics} errorElement={<p>Failed to load</p>}>
{(data) => <Chart data={data} />}
</Await>
</Suspense>
When to stream: Analytics, comments, recommendations, secondary content below the fold. When NOT to stream: Auth state, page title, SEO-critical content, data for page structure.
See examples/deferred.md for complete streaming examples.
Pattern 5: useFetcher for Non-Navigation Mutations
useFetcher enables data loading and mutations without page navigation. Essential for inline interactions.
const fetcher = useFetcher();
// Optimistic UI: show expected state immediately
const optimisticIsLiked = fetcher.formData
? fetcher.formData.get("liked") === "true"
: isLiked;
Use <Form> for: Create/login/wizards -- actions that should change the URL.
Use useFetcher for: Like buttons, toggles, inline editing, search autocomplete.
See examples/optimistic.md for optimistic UI and debounced search.
Pattern 6: Error Boundaries
Export ErrorBoundary from route modules. Distinguish between thrown Response errors and unexpected JavaScript errors.
export function ErrorBoundary() {
const error = useRouteError();
if (isRouteErrorResponse(error)) {
// Thrown Response: render status-specific UI
return <div role="alert"><h1>{error.status}</h1></div>;
}
if (error instanceof Error) {
// Unexpected error: generic fallback
return <div role="alert"><h1>Unexpected Error</h1></div>;
}
return <div role="alert"><h1>Unknown Error</h1></div>;
}
Key rules:
- Throw
json({ message }, { status: 404 })for expected errors - ErrorBoundary is route-scoped -- rest of the page stays functional
- Use named constants for HTTP status codes
isRouteErrorResponse()checks if error was a thrown Response
See examples/error-handling.md for multi-status error boundaries.
Pattern 7: Meta and Links Functions
Export meta for SEO metadata and links for stylesheets/preloads.
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [{ title: "Not Found" }];
return [
{ title: `${data.post.title} | ${SITE_NAME}` },
{ property: "og:title", content: data.post.title },
{ tagName: "link", rel: "canonical", href: url },
];
};
Gotcha: meta function receives null data on error -- always handle the missing data case.
Gotcha: links function cannot access loader data -- use meta with tagName: "link" for dynamic links.
See examples/meta.md for Open Graph and Twitter Card patterns.
Pattern 8: Resource Routes
Routes without a default export become resource routes -- useful for APIs, webhooks, and file downloads.
// app/routes/api.health.ts (no default export = resource route)
export async function loader() {
return json({ status: "healthy", timestamp: new Date().toISOString() });
}
See examples/resource-routes.md for webhook and file download examples.
Pattern 9: Nested Routes and Layouts
Nested routes share parent layouts and load data in parallel. Parent loaders provide shared data, child loaders run concurrently.
| Pattern | Purpose |
|---|---|
admin.tsx | Layout (has <Outlet />) |
admin._index.tsx | Index route (renders at parent URL) |
admin.users.tsx | Nested child route |
admin_.settings.tsx | Escapes parent layout with trailing underscore |
_auth.tsx | Pathless layout with leading underscore |
See examples/nested-routes.md for admin layout and pathless layout examples.
Detailed Resources:
- examples/core.md - File-based routing, route naming, essential hooks
- examples/loaders.md - Protected routes, pagination, caching headers
- examples/actions.md - Signup forms, validation, delete with confirmation
- examples/forms.md - Multiple forms in one route, intent pattern
- examples/nested-routes.md - Layouts, pathless routes, admin panels
- examples/error-handling.md - Multi-status error boundaries
- examples/optimistic.md - Optimistic UI, debounced search
- examples/deferred.md - Streaming with defer/Promises
- examples/resource-routes.md - API endpoints, webhooks, file downloads
- examples/meta.md - SEO meta tags, Open Graph, Twitter Cards
- examples/react-router-v7.md - Migration: routes.ts, type generation, clientAction, Single Fetch
- reference.md - Decision frameworks, anti-patterns, route module exports
<red_flags>
RED FLAGS
High Priority Issues:
- Loaders/actions exported from non-route files -- Remix only runs these from route modules
- Missing type inference -- always use
useLoaderData<typeof loader>()orRoute.ComponentProps - Client-side data fetching with useEffect + fetch -- use loaders for server data
- Returning null from loader instead of throwing Response -- every consumer must null-check
Medium Priority Issues:
- Streaming critical data (page title, auth state) -- causes content flicker
- useFetcher without optimistic UI -- makes interactions feel slow
- Magic numbers for HTTP status codes -- use named constants
- Form without
method="post"-- defaults to GET, action not called
Gotchas & Edge Cases:
- Loader runs on every navigation -- even for child route changes, parent loaders re-run (use
shouldRevalidateto optimize) - Action runs before all loaders -- after action, all loaders revalidate by default
defer()requires<Suspense>+<Await>wrapper -- forgetting causes errors- Index routes need
?indexquery param for form actions targeting them metafunction receives null data on error -- must handle missing data caselinksfunction cannot access loader data -- usemetawithtagName: "link"for dynamic links- In React Router v7,
clientActiontakes priority when bothactionandclientActionexist -- server action is completely skipped
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
All code must follow project conventions in CLAUDE.md
(You MUST export loaders and actions as named exports from route modules only -- they do not work in non-route files)
(You MUST throw Response objects for expected errors (404, 403) -- use ErrorBoundary for handling)
(You MUST await critical data and return non-critical data as Promises for streaming)
(You MUST use named constants for HTTP status codes -- no magic numbers)
Failure to follow these rules will break data loading, type safety, and error handling.
</critical_reminders>
Frequently asked questions
What to verify before installation and use
What does the web-meta-framework-remix source document cover?
Quick Guide: Each route exports a loader for reads and an action for writes. Both run on the server. Data flows through loaders, mutations go through actions, forms work without JavaScript, and nested routes enable parallel data loading. json() and defer() are deprecated in Reac…
How do I install web-meta-framework-remix?
The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/web-meta-framework-remix". Inspect the command and pinned source before running it.
Which permission-related actions were detected?
Static rules flagged network in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
event4u-app/agent-config
existing-ui-audit
Use BEFORE writing or editing any non-trivial UI — inventories components, design tokens, shadcn primitives, and reusable patterns into state.ui_audit. Hard gate for the ui directive set.
kensaurus/cursor-kenji
enhance-web-web3d
Add purposeful 3D/WebGL and scroll choreography to an existing site with Three.js/R3F, GSAP, or Motion. Use when "add 3D", "WebGL hero", "React Three Fiber", or "scroll-driven 3D". General UI polish → enhance-web-ui. Motion without 3D → enhance-motion.
UiPath/skills
uipath-coded-apps
UiPath Coded Apps — scaffold, build, run, and deploy Coded Web Apps and Coded Action Apps: React/TypeScript apps that call UiPath Cloud APIs via the `@uipath/uipath-typescript` SDK and ship to Automation Cloud (push/pull to Studio Web, pack, publish, deploy, OAuth-PKCE). Also generates live analytics & governance dashboards from a plain-language request, wired to tenant data via the Insights real-time API, with edit and deploy flows. For RPA→uipath-rpa, Python agents→uipath-agents, Maestro flows
hyperfx-ai/marketing-skills
slack
Slack messaging, file sharing, Block Kit formatting, and channel management. Use when the user wants to send Slack messages, post rich Block Kit layouts, share files, react, or manage channels and members.