remixjs-best-practices
Best practices for Remix (2025-2026 Edition), focusing on React Router v7 migration, server-first data patterns, and error handling.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Best practices for Remix (2025-2026 Edition), focusing on React Router v7 migration, server-first data patterns, and error handling.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create, critique, regenerate, or validate Shopify App Store app logos/icons using Shopify's current app icon guidance. Use when the user asks for a Shopify app logo, Shopify App Store icon, app listing icon, Dev Dashboard app icon, branded square logo, logo prompt, icon validation, or review-safe visual direction for Shopify app submission.
Create, critique, or regenerate Shopify App Store feature images for app listings using Shopify's current App Store media guidance and the $imagegen skill for actual image generation/editing. Use when the user asks for a Shopify app feature image, App Store listing hero image, marketing image, listing media, image prompt, image validation, or review-safe visual direction for Shopify app submission.
Create comprehensive Shopify App Store listing content following official best practices. Use when users need to write or improve their app listing for the Shopify App Store, including app introduction, app details, features, app card subtitle, search terms, SEO content (title tag, meta description), and testing instructions. Also applicable when preparing an app submission for Shopify review.
Generate and maintain changelogs following Keep a Changelog format. Analyzes git commits, categorizes changes, and produces well-structured release notes.
Guide for implementing Shopify's Billing API in Remix apps using @shopify/shopify-app-remix. Covers subscriptions, one-time purchases, usage-based billing, discounts, and the project's billing implementation patterns.
Comprehensive code investigation and audit tool. Discovers all project features, then dispatches parallel subagents to analyze issues, risks, dead code, missing functionality, and redundancies. Produces a prioritized risk report. Use this skill when the user asks to "investigate code", "audit project", "find risks", "check code quality", "analyze codebase", "what's wrong with this code", "project health check", "code review entire project", "find dead code", "find redundant code", or any request for a thorough codebase analysis.
| name | remixjs-best-practices |
| description | Best practices for Remix (2025-2026 Edition), focusing on React Router v7 migration, server-first data patterns, and error handling. |
This skill outlines modern best practices for building scalable, high-performance applications with Remix, specifically focusing on the transition to React Router v7 and future-proofing for Remix v3.
remix.config.js or vite.config.ts to ensuring smooth migration.npx codemod remix/2/react-router/upgrade to migrate existing v2 apps.Avoid client-side fetching (useEffect) unless absolutely necessary.
// ✅ Good: Typed loader with single strict return
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUser(request);
if (!user) throw new Response("Unauthorized", { status: 401 });
return json({ user });
};
// Component gets fully typed data
export default function Dashboard() {
const { user } = useLoaderData<typeof loader>();
return <h1>Hello, {user.name}</h1>;
}
onClickUse HTML Forms (or Remix <Form>) for mutations. This works without JS and handles race conditions automatically.
// ✅ Good: Descriptive, declarative mutation
<Form method="post" action="/update-profile">
<button type="submit">Save</button>
</Form>
Design features to work without JavaScript first. Remix handles the "hydration" to make it interactive (SPA feel) automatically.
Do not rely solely on a root ErrorBoundary. Place boundaries in nested routes to prevent a partial failure from crashing the entire page.
// routes/dashboard.tsx (Nested Route)
export function ErrorBoundary() {
const error = useRouteError();
return <div className="p-4 bg-red-50">Widget crashed: {error.message}</div>;
}
throw new Response(...). Caught by specific logic or boundaries.Return errors from actions, don't throw them. This preserves user input.
// Action
if (name.length < 3) {
return json({ errors: { name: "Too short" } }, { status: 400 });
}
// Component
const actionData = useActionData<typeof action>();
{actionData?.errors?.name && <span>{actionData.errors.name}</span>}
Cache-Control HeadersLoaders can output cache headers. Use them for public data.
export const loader = async () => {
return json(data, {
headers: { "Cache-Control": "public, max-age=3600" }
});
};
Use defer for slow data (e.g., third-party APIs) to unblock the initial HTML render.
export const loader = async () => {
const critical = await getCriticalData();
const slow = getSlowData(); // Promise
return defer({ critical, slow });
};
// UI supports <Suspense> for the slow part