agentleFS
G1JoshiG1Joshi/Agent-Skills/skills/frameworks/remix/SKILL.md

remix

Skill15 starsChanged 42 days agoMITView on GitHub

Expert Remix (React Router v7) assistance covering Loaders, Actions, nested routing, optimistic UI, and Web Fetch standards. Use when developing resilient, full-stack React web applications.

7 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 7 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use Remix loaders and actions for declarative data synchronization:

    line 149
  2. Very specific:

    Use useFetcher for mutations that do not require full page navigation (e.g.

    line 195
  3. Very specific:

    Use client-side useEffect for data fetching when loader functions exist.

    line 201

“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Remix

Remix is a full-stack web framework built on web standards (Fetch API, Request/Response), providing nested routing, resilient form mutations, and seamless Vite integration.

When to Use

  • Web Standards-First Full-Stack Applications: Utilizing standard Request, Response, and HTML forms via Remix / React Router v7.
  • High-Performance Server-Rendered Applications: Instant page transitions with nested routing and parallel data loading.
  • Resilient Web Apps with Progressive Enhancement: Applications that function reliably before JavaScript has loaded.
  • Optimistic UI & Mutation Heavy Interfaces: Using useFetcher and server actions without bespoke client state machines.

Quick Start

import { json } from "@remix-run/node";
import { useLoaderData, Form } from "@remix-run/react";

// Functions run on server
export async function loader() {
  return json(await db.getTasks());
}

export async function action({ request }) {
  const formData = await request.formData();
  await db.createTask(formData.get("title"));
  return json({ ok: true });
}

// Component runs on Client + Server
export default function Tasks() {
  const tasks = useLoaderData<typeof loader>();
  return (
    <Form method="post">
      <input name="title" />
      <button>Add</button>
    </Form>
  );
}

Core Concepts

Nested Routing & Parallel Loader Data Loading

Fetching server-side data per route segment in parallel:

// app/routes/users.$id.tsx
import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData, Link } from "@remix-run/react";

export async function loader({ params }: LoaderFunctionArgs) {
  const userId = params.id;
  const user = await db.user.findUnique({ where: { id: userId } });

  if (!user) {
    throw new Response("User Not Found", { status: 404 });
  }

  return json({ user });
}

export default function UserDetailRoute() {
  const { user } = useLoaderData<typeof loader>();

  return (
    <div className="user-card">
      <h2>{user.name}</h2>
      <p>{user.email}</p>
      <Link to="edit">Edit Profile</Link>
    </div>
  );
}

Route Actions & HTML Form Submission

Standard HTTP POST handling with automatic revalidation:

// app/routes/users.$id.edit.tsx
import { redirect, type ActionFunctionArgs } from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";

export async function action({ request, params }: ActionFunctionArgs) {
  const formData = await request.formData();
  const name = formData.get("name") as string;

  if (!name || name.length < 3) {
    return { error: "Name must be at least 3 characters" };
  }

  await db.user.update({ where: { id: params.id }, data: { name } });
  return redirect(`/users/${params.id}`);
}

export default function EditUserRoute() {
  const actionData = useActionData<typeof action>();

  return (
    <Form method="post">
      <input name="name" placeholder="Full Name" />
      {actionData?.error && <span className="error">{actionData.error}</span>}
      <button type="submit">Update</button>
    </Form>
  );
}

Granular ErrorBoundaries per Route Segment

Isolating errors without crashing the entire page hierarchy:

import { isRouteErrorResponse, useRouteError } from "@remix-run/react";

export function ErrorBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error)) {
    return (
      <div className="route-error">
        <h1>
          {error.status} {error.statusText}
        </h1>
        <p>{error.data}</p>
      </div>
    );
  }

  return (
    <div className="route-error">Unexpected application error occurred.</div>
  );
}

Common Patterns

Loader and Action Data Cycle

Problem: Managing separate state stores, loading states, and error handling for form submissions.

Solution: Use Remix loaders and actions for declarative data synchronization:

import {
  json,
  type LoaderFunctionArgs,
  type ActionFunctionArgs,
} from "@remix-run/node";
import { useLoaderData, Form } from "@remix-run/react";

export async function loader({ request }: LoaderFunctionArgs) {
  const todos = await db.todos.findMany();
  return json({ todos });
}

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  await db.todos.create({ title: formData.get("title") });
  return json({ ok: true });
}

export default function TodosPage() {
  const { todos } = useLoaderData<typeof loader>();
  return (
    <div>
      <Form method="post">
        <input name="title" required />
        <button type="submit">Add Todo</button>
      </Form>
      <ul>
        {todos.map((t) => (
          <li key={t.id}>{t.title}</li>
        ))}
      </ul>
    </div>
  );
}

Best Practices

Do:

  • Leverage Remix / React Router v7 unified framework features for universal full-stack execution.
  • Build mutations with native <Form> components to guarantee progressive enhancement.
  • Co-locate loader, action, and component in the same route file for atomic cohesion.
  • Use useFetcher for mutations that do not require full page navigation (e.g. upvotes, inline toggles).

Don't:

  • Manage client cache state manually; Remix automatically revalidates loader data after actions.
  • Return huge, unneeded relational payloads from loaders; return lean, serialized data.
  • Use client-side useEffect for data fetching when loader functions exist.

Troubleshooting

ErrorCauseSolution
Error: You must return a Response from loader/actionLoader or action did not return a value or returned undefined.Return json({ data }) or new Response(...).
Form data empty in actionForm inputs missing name attribute.Ensure every <input> inside <Form> has a unique name attribute.
Root boundary caught errorUnhandled error in child route without local ErrorBoundary.Export ErrorBoundary component in route to catch local exceptions.

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.