Remix Cursor Rules: React Web Framework Guide
Cursor rules for Remix development covering nested routes, loader/action patterns, form handling, error boundaries, and server-side rendering with enhanced UX.
Overview
Remix is a full-stack React framework that emphasizes web fundamentals, nested routing, and progressive enhancement for superior user experiences. These cursor rules enforce strict loader/action data flow, robust form handling, and error boundary patterns to help AI assistants generate fast, resilient web applications. Whether you're handling complex mutations or optimizing server-side data loading, these rules ensure your application remains highly performant and accessible without compromising UX.
Note:
Enforces loader/action patterns, form handling conventions, error boundaries, and server-side rendering best practices.
Rules Configuration
---
description: Enforces best practices for Remix development, focusing on loader/action data flow, form handling, error boundaries, and progressive enhancement. Provides comprehensive guidelines for writing clean, resilient full-stack React applications with proper context.
globs: **/*.{js,jsx,ts,tsx}
---
# Remix Best Practices
You are an expert in Remix development and related web technologies.
You understand modern Remix development practices, architectural patterns, and the importance of providing complete context in code generation.
### Context-Aware Code Generation
- Provide route context including params, loader data types, and URL state
- Include relevant configs (remix.config.js, tsconfig.json) when scaffolding
- Generate complete loader/action signatures with typed params and responses
- Document route hierarchy and parent/child data dependencies
### Loader & Action Patterns
- Use loaders for GET requests to fetch and return data server-side
- Use actions for POST/PUT/DELETE mutations with form data
- Return typed JSON responses using json() utility from @remix-run/node
- Use useLoaderData and useActionData for type-safe access in components
- Implement resource routes for API endpoints and file downloads
### Form Handling & Progressive Enhancement
- Use `<Form>` over native `<form>` for JavaScript-enhanced submissions
- Validate and sanitize inputs inside action functions, not client-side
- Return validation errors from action and display via useActionData
- Use useNavigation for loading states and optimistic UI
- Support JavaScript-disabled clients with proper form fallbacks
### Routing & Nested Layouts
- Use file-based routing in /app/routes with flat or nested folder structure
- Leverage parent loaders to avoid redundant data fetching in child routes
- Use `<Outlet>` for nested layout rendering with persistent parent UI
- Implement layout routes with _layout convention for shared shells
### Error Boundaries & Best Practices
- Use ErrorBoundary for 500-level server errors per route
- Use CatchBoundary for thrown Response objects (404, 401)
- Provide fallback UI for each route segment to isolate failures
- Use TypeScript throughout for type-safe loader and action data
- Prefer server-side logic for data fetching; keep client for interactivity
- Add type-safe form validation with zod schemas in actions
- Include proper error handling in all loaders and actions
Installation
Create remix.mdc in your project's .cursor/rules/ directory and paste the configuration above. Cursor and Windsurf both read .cursor/rules/ — Copilot users place it in .github/copilot-instructions.md instead.
Examples
// app/routes/posts.$id.tsx — Loader and action with typed responses
import type { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node"
import { json } from "@remix-run/node"
import { useLoaderData, Form } from "@remix-run/react"
export async function loader({ params }: LoaderFunctionArgs) {
const post = await getPost(params.id)
if (!post) throw new Response("Not Found", { status: 404 })
return json({ post })
}
export async function action({ request, params }: ActionFunctionArgs) {
const formData = await request.formData()
const title = formData.get("title")
await updatePost(params.id, { title })
return json({ success: true })
}
export default function Post() {
const { post } = useLoaderData<typeof loader>()
return (
<Form method="post">
<input name="title" defaultValue={post.title} />
<button type="submit">Save</button>
</Form>
)
}
Related Resources
Related Articles
AI Rules in Modern IDEs: Global and Project-Specific Configurations
AI rules customize AI assistants in modern IDEs like Cursor, Windsurf, and VSCode Copilot. Learn to configure global and project-specific rules for consistent, high-quality code.
C# Cursor Rules: .NET Development Best Practices
Cursor rules for C# and .NET development covering async patterns, LINQ, dependency injection, Entity Framework, and clean architecture for enterprise applications.
Elixir Cursor Rules: AI-Powered Development Best Practices
Cursor rules for Elixir development enforcing official style guides, modern Elixir 1.12+ features, and clean code principles with AI assistance for production-ready code.