К основному содержанию
скилл CX Codex

remix — скилл для Claude Code: Remix, loaders и actions

Скилл для ИИ-агента, который подсказывает, как писать Remix-приложения на TypeScript: загрузка данных, мутации и вложенные маршруты.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add Mindrally/skills --skill remix -a claude-code
Открыть на GitHub

Что делает remix

Скилл задаёт агенту роль эксперта по Remix, React и TypeScript. Внутри — набор правил и примеров кода: базовый loader с useLoaderData, loader с проверкой сессии и редиректом, action для обработки форм с валидацией и возвратом ошибок, useFetcher для запросов без перехода по маршруту и оптимистичного UI.

Отдельно разобраны вложенные маршруты: layout-маршруты с Outlet, pathless-макеты вроде _auth.tsx, ресурсные маршруты без UI, ErrorBoundary с useRouteError, мета-теги через MetaFunction и подключение стилей через LinksFunction. Есть раздел про сессии: createCookieSessionStorage, флаг httpOnly, sameSite: 'lax' и секрет из process.env.SESSION_SECRET.

Структура проекта описана деревом каталогов app/ с routes/, models/, utils/ и файлами entry.client.tsx, entry.server.tsx, root.tsx. В конце — советы по производительности: prefetch="intent" у ссылок, defer для потоковой передачи данных, разбиение кода динамическими импортами. Если ваш проект не на Remix, скилл будет тянуть агента в эту архитектуру — это повод проверить, стоит ли его вообще подключать.

Какие задачи решает

  • написать loader с загрузкой данных по параметру маршрута
  • обработать отправку формы через action и вернуть ошибки валидации
  • сделать вложенный layout с Outlet и pathless-макетом
  • добавить оптимистичное удаление элемента через useFetcher
  • настроить сессию в cookie с httpOnly и секретом

Примеры запросов агенту

  • Сгенерируй маршрут routes/posts/$slug.tsx с loader, который достаёт пост по slug и кидает 404, если его нет
  • Сделай action для формы создания поста с проверкой поля title и редиректом на страницу поста
  • Покажи, как через useFetcher сделать кнопку лайка без перехода на другой маршрут

Как установить remix

1Через Skills CLI (Vercel)

npx skills add Mindrally/skills --skill remix -a claude-code

2Вручную: положить файлы

~/.claude/skills/remix/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/remix/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о remix

Как установить remix в Claude?

Выполните npx skills add Mindrally/skills --skill remix -a claude-code. Файл скилла появится по пути ~/.claude/skills/remix/SKILL.md.

Что делает скилл remix?

Даёт агенту инструкции по разработке на Remix: примеры loader и action, вложенные маршруты, useFetcher, границы ошибок и работа с сессиями на TypeScript.

С какими платформами работает remix?

Скилл ставят в Claude, Codex, Cursor, GitHub Copilot, Gemini CLI и OpenCode — для каждой платформы своя команда установки.

Исходный текст

SKILL.md · Apache-2.0
---
name: remix
description: Expert guidance for Remix development with TypeScript, loaders/actions, nested routes, and full-stack web application best practices
metadata:
  maintainer: Mindrally
  source: https://github.com/Mindrally/skills
---

# Remix Development

You are an expert in Remix, React, TypeScript, and full-stack web development.

## Key Principles

- Write concise, technical Remix code with accurate TypeScript examples
- Embrace progressive enhancement and web standards
- Use loaders for data fetching and actions for mutations
- Leverage nested routes for code organization
- Prioritize server-side rendering and web fundamentals

## Project Structure

```
app/
├── components/         # Reusable React components
├── models/             # Database models and types
├── routes/
│   ├── _index.tsx      # / route
│   ├── about.tsx       # /about route
│   └── posts/
│       ├── _index.tsx  # /posts route
│       └── $slug.tsx   # /posts/:slug route
├── styles/             # CSS files
├── utils/              # Utility functions
├── entry.client.tsx    # Client entry
├── entry.server.tsx    # Server entry
└── root.tsx            # Root layout
```

## Loaders

### Basic Loader
```typescript
import type { LoaderFunctionArgs } from '@remix-run/node';
import { json } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';

export async function loader({ params }: LoaderFunctionArgs) {
  const post = await getPost(params.slug);

  if (!post) {
    throw new Response('Not Found', { status: 404 });
  }

  return json({ post });
}

export default function PostRoute() {
  const { post } = useLoaderData<typeof loader>();

  return <article>{post.content}</article>;
}
```

### Loader with Authentication
```typescript
import { redirect } from '@remix-run/node';
import { getUser } from '~/utils/session.server';

export async function loader({ request }: LoaderFunctionArgs) {
  const user = await getUser(request);

  if (!user) {
    throw redirect('/login');
  }

  return json({ user });
}
```

## Actions

### Form Handling
```typescript
import type { ActionFunctionArgs } from '@remix-run/node';
import { json, redirect } from '@remix-run/node';

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const title = formData.get('title');
  const content = formData.get('content');

  const errors: Record<string, string> = {};

  if (!title) {
    errors.title = 'Title is required';
  }

  if (Object.keys(errors).length > 0) {
    return json({ errors }, { status: 400 });
  }

  const post = await createPost({ title, content });

  return redirect(`/posts/${post.slug}`);
}
```

### Using Action Data
```typescript
import { useActionData, Form } from '@remix-run/react';

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

  return (
    <Form method="post">
      <input name="title" type="text" />
      {actionData?.errors?.title && (
        <p className="error">{actionData.errors.title}</p>
      )}
      <textarea name="content" />
      <button type="submit">Create Post</button>
    </Form>
  );
}
```

## Nested Routes

### Layout Routes
```typescript
// routes/dashboard.tsx (layout)
import { Outlet } from '@remix-run/react';

export default function DashboardLayout() {
  return (
    <div className="dashboard">
      <nav>
        <Link to="/dashboard">Overview</Link>
        <Link to="/dashboard/settings">Settings</Link>
      </nav>
      <main>
        <Outlet />
      </main>
    </div>
  );
}
```

### Pathless Layouts
```typescript
// routes/_auth.tsx (pathless layout for /login, /register)
export default function AuthLayout() {
  return (
    <div className="auth-container">
      <Outlet />
    </div>
  );
}
```

## useFetcher

### Non-Navigation Fetches
```typescript
import { useFetcher } from '@remix-run/react';

export default function LikeButton({ postId }: { postId: string }) {
  const fetcher = useFetcher();
  const isLiking = fetcher.state !== 'idle';

  return (
    <fetcher.Form method="post" action="/api/like">
      <input type="hidden" name="postId" value={postId} />
      <button type="submit" disabled={isLiking}>
        {isLiking ? 'Liking...' : 'Like'}
      </button>
    </fetcher.Form>
  );
}
```

### Optimistic UI
```typescript
export default function TodoItem({ todo }: { todo: Todo }) {
  const fetcher = useFetcher();

  const isDeleting = fetcher.formData?.get('_action') === 'delete';

  if (isDeleting) {
    return null; // Optimistically remove
  }

  return (
    <li>
      {todo.title}
      <fetcher.Form method="post">
        <input type="hidden" name="_action" value="delete" />
        <input type="hidden" name="id" value={todo.id} />
        <button type="submit">Delete</button>
      </fetcher.Form>
    </li>
  );
}
```

## Error Boundaries

```typescript
import { useRouteError, isRouteErrorResponse } from '@remix-run/react';

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

  if (isRouteErrorResponse(error)) {
    return (
      <div>
        <h1>{error.status} {error.statusText}</h1>
        <p>{error.data}</p>
      </div>
    );
  }

  return (
    <div>
      <h1>Error</h1>
      <p>{error instanceof Error ? error.message : 'Unknown error'}</p>
    </div>
  );
}
```

## Resource Routes

```typescript
// routes/api/posts.tsx
import { json } from '@remix-run/node';

export async function loader() {
  const posts = await getPosts();
  return json(posts);
}

// No default export = resource route (no UI)
```

## Meta and Links

```typescript
import type { MetaFunction, LinksFunction } from '@remix-run/node';

export const meta: MetaFunction<typeof loader> = ({ data }) => {
  return [
    { title: data?.post.title ?? 'Blog' },
    { name: 'description', content: data?.post.excerpt },
  ];
};

export const links: LinksFunction = () => {
  return [
    { rel: 'stylesheet', href: styles },
    { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
  ];
};
```

## Session Management

```typescript
// utils/session.server.ts
import { createCookieSessionStorage, redirect } from '@remix-run/node';

const sessionStorage = createCookieSessionStorage({
  cookie: {
    name: '__session',
    httpOnly: true,
    path: '/',
    sameSite: 'lax',
    secrets: [process.env.SESSION_SECRET!],
    secure: process.env.NODE_ENV === 'production',
  },
});

export async function createUserSession(userId: string, redirectTo: string) {
  const session = await sessionStorage.getSession();
  session.set('userId', userId);

  return redirect(redirectTo, {
    headers: {
      'Set-Cookie': await sessionStorage.commitSession(session),
    },
  });
}
```

## Performance

- Prefetch with `<Link prefetch="intent">`
- Use `defer` for streaming data
- Implement stale-while-revalidate with headers
- Code split with dynamic imports
- Cache loader responses appropriately

## Best Practices

- Always validate form data on the server
- Use TypeScript for type safety
- Handle loading and error states
- Implement proper CSRF protection
- Use progressive enhancement
- Test with JavaScript disabled

© Mindrally · Apache-2.0 · Mindrally/skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →
tanstack-router-best-practices DeckardGer Набор правил по TanStack Router для React: типизация, загрузка данных, search params и навигация. Пригодится, когда роутинг в проекте разрастается. CX Codex +1 7 100установок tanstack-router tanstack-skills Скилл по TanStack Router для React и Solid: файловый роутинг, поисковые параметры и загрузка данных с проверкой типов. CX Codex +1 4 900установок router-core TanStack Скилл-навигатор по TanStack Router: разводит задачу по подскиллам и напоминает про вывод типов и клиентские лоадеры, на которых агенты ломаются. CX Codex +1 589установок react-router-v7 existential-birds Скилл с практиками React Router v7: подсказывает, когда брать loader, Form или fetcher, и как настраивать вложенные маршруты. CX Codex +1 572установок react-router TanStack Скилл для агента по @tanstack/react-router: справочник хуков и компонентов плюс сборка файлового роутинга на Vite от установки до routeTree.gen. CX Codex +1 547установок nextjs-dynamic-routes-params wsimmonds Скилл подсказывает агенту, как строить динамические сегменты App Router и читать params в Next.js 15+. Пригодится, когда страницы зависят от ID или слага из URL. CX Codex +1 303установок

Из того же набора168

supabase-development Задаёт агенту порядок работы с Supabase: схема базы, RLS-политики, авторизация, realtime-подписки и Edge Functions. CX Codex +1 699установок monorepo Скилл задаёт агенту набор правил для монорепозиториев на TypeScript, React, Next.js и Expo с Turbo. Пригодится, когда в одном репозитории живут несколько приложений и общих пакетов. CX Codex +1 694установок meta-prompt Скилл с набором мета-промптов: критикует ответы модели, разбирает ход решения и ставит оценку. Пригодится, когда нужно проверить качество ответа агента. CX Codex +1 691установок cloudflare-development Скилл с правилами разработки на edge-платформе Cloudflare: Workers, Pages, KV, D1, R2 и Durable Objects. Пригодится, когда агент пишет код для воркеров или настраивает wrangler.toml. CX Codex +1 689установок salesforce-dx Скилл задаёт агенту правила разработки на Salesforce DX: Apex, триггеры, LWC, scratch orgs и выкладка через SFDX CLI. CX Codex +1 688установок micronaut Задаёт агенту конвенции Micronaut: DI на этапе компиляции, нативные сборки GraalVM, реактивные сервисы. Пригодится, когда проект на Java и хочется, чтобы кодогенерация шла по фреймворку, а не наугад. CX Codex +1 687установок julia Задаёт агенту стиль кода на Julia: мультиметоды, типы, тесты и оптимизацию производительности. Пригодится, если пишете научные расчёты или численные библиотеки. CX Codex +1 687установок clerk-authentication Правила подключения Clerk в Next.js: middleware, хуки, защита серверных действий и маршрутов API. Пригодится, когда проект уже на Clerk и нужен порядок в проверках доступа. CX Codex +1 683установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой