Agent RulesAgent Rules
Builder
Options
Browse all rules by language and framework
Templates
Pre-built rule sets ready to use
Popular Rules
Top community-ranked rules leaderboard
GuidesAnalyzePricingContact
Builder
OptionsTemplatesPopular Rules
GuidesAnalyzePricingContact

Product

  • Builder
  • Templates
  • Browse Rules
  • My Library

Learn

  • What are AI Agent Rules?
  • Guides
  • FAQ
  • About

Resources

  • Terms
  • Privacy Policy
  • Pricing
  • Contact
  • DMCA Policy

Support

Help keep this project free.

Agent RulesAgent Rules Builder
© 2026 Aurora Algorithm Inc.
Back to Templates

TypeScript + Remix

Rules for Remix applications with loader/action patterns, nested routing, form handling, error boundaries, and progressive enhancement strategies.

typescriptTypeScript/remixRemix
typescript
remix
react
full-stack
progressive-enhancement
Customize in Builder

Details

Language
typescriptTypeScript
Framework
remixRemix

Rules Content

AGENTS.md
Edit in Builder

TypeScript Remix Agent Rules

Project Context

- Use Remix v2+ with TypeScript strict mode, Vite build, and `@remix-run/react`.
- Follow flat-file routing in `app/routes/` with dot-delimited names for nested layouts.
- Store server-only code (DB, secrets, auth) in `app/lib/.server/` — Remix tree-shakes it from the client.
- Embrace the web platform: use `Request`, `Response`, `Headers`, and `FormData` natively.

Code Style & Structure

- Use named exports for `loader`, `action`, `meta`, `headers`, and `ErrorBoundary`. Default export for the component.
- Order route file exports: imports, types, `loader`, `action`, `meta`, `headers`, component, `ErrorBoundary`.
- Keep route modules focused. Extract model queries into `app/models/` and business logic into `app/lib/`.
- Use `invariant(condition, message)` from `tiny-invariant` for runtime assertions.
- Use descriptive names with auxiliary verbs: `isSubmitting`, `hasAccess`, `canDelete`.

TypeScript Patterns

- Use `typeof loader` for `useLoaderData<typeof loader>()` — never manually define loader return types.
- Use `typeof action` for `useActionData<typeof action>()` — Remix infers the union with `null`.
- Use `inferRouterInputs<Router>` and `inferRouterOutputs<Router>` for tRPC-integrated routes.
- Type `params` with `LoaderFunctionArgs` or cast with `params.id as string` after validating existence.
- Use `satisfies` to check objects match expected shapes without widening the type.
- Use discriminated unions for form state: `type FormState = { status: 'idle' } | { status: 'error'; errors: Record<string, string> }`.

Loaders

- Return plain objects from loaders — Remix v2 wraps them automatically without `json()`.
- Throw `Response` objects for expected HTTP errors: `throw new Response('Not Found', { status: 404 })`.
- Use `defer()` to stream non-critical data using `<Await>` and `<Suspense>` on the page.
- Use `redirect(url)` inside loaders to guard routes based on authentication state.
- Validate and parse URL search params with Zod in loaders for type-safe pagination and filtering.

Actions

- Always redirect after a successful mutation using `redirect('/path')` — prevents form resubmission.
- Validate `formData` with Zod schemas. Return validation errors as `{ errors: Record<string, string[]> }`.
- Use the `intent` hidden input to distinguish multiple actions on the same page.
- Use `useSubmit()` for programmatic form submission (auto-save, debounced search queries).

Forms & Progressive Enhancement

- Use `<Form method="post">` which works without JavaScript — enhance with `useFetcher` for inline mutations.
- Use `useFetcher` for mutations that should not trigger full-page navigation (likes, toggles, inline edits).
- Show pending UI with `navigation.state === 'submitting'` or `fetcher.state === 'submitting'`.
- Implement optimistic UI by reading `fetcher.formData` to display the expected post-mutation state.

Error Boundaries

- Export `ErrorBoundary` from every route with a loader or action.
- Use `isRouteErrorResponse(error)` to distinguish `Response` throws from unexpected JavaScript errors.
- Nest error boundaries — child route errors must not break the parent layout render.
- Export `ErrorBoundary` from `app/root.tsx` as the global fallback.

Session & Security

- Use `createCookieSessionStorage` with `httpOnly: true`, `secure: true`, `sameSite: 'lax'`.
- Store only user ID and role in sessions — fetch full user data in loaders to keep session cookies small.
- Implement CSRF protection with a session token validated in all mutation actions.
- Create `requireUser(request)` and `requireRole(request, role)` helpers in `app/lib/.server/auth.ts`.

Error Handling

- Use `throw new Response(message, { status })` for expected failures — Remix routes them to `ErrorBoundary`.
- Log unexpected errors with structured context (request URL, user ID) before returning a generic error response.
- Return 422 for validation errors, 401 for auth, 403 for authorization, 404 for missing resources.

Performance

- Use `prefetch="intent"` on `<Link>` components to load data on hover before the user clicks.
- Set `Cache-Control` headers from loaders for static or slowly-changing data using the `headers` export.
- Minimize client JavaScript — rely on server rendering, progressive enhancement, and `<Form>`.
- Use `defer` with `<Await>` for slow data sources (third-party APIs) to avoid blocking the entire page.

Testing

- Test loaders and actions as plain async functions by constructing mock `Request` objects.
- Use `createRemixStub` from `@remix-run/testing` for route integration tests with real loaders.
- Test error boundaries by making test loaders throw and asserting fallback UI renders.
- Write E2E tests with Playwright for authentication flows and critical form submissions.

Related Templates

typescript

Next.js + TypeScript

Production-ready rules for Next.js applications with TypeScript, App Router, and React Server Components.

typescript

React + TypeScript

Modern React with TypeScript, hooks-first patterns, and component best practices.

typescript

React Performance

Eliminate render waterfalls, reduce bundle size, and optimize server and client rendering in React applications.