- Fill in your project-specific details
- Remove examples that don't apply to your project
- Adjust rules to match your team's conventions
This template is generalized from a production SaaS setup. Adapt as needed.
-->
Critical Rules
These rules address recurring mistakes that cause real issues. Each one prevents debugging time, security vulnerabilities, or broken builds:
- Using
any defeats TypeScript's safety net — bugs and security issues reach production undetected. Use proper types or unknown.
console.log/console.error in production breaks structured logging, making production debugging impossible. Use a proper logger (e.g., Pino, Winston, or your framework's logging utility).
- Missing
import 'server-only' allows server code to bundle into the client, leaking API keys and database credentials to the browser.
- Server actions must validate inputs with Zod schemas and verify authentication before processing. Unauthenticated or unvalidated data must never reach the database.
- Tables without RLS expose all rows to any authenticated user — one missing policy means customer data leaks across accounts.
- Forgetting to
await params in async server components causes runtime errors in Next.js that are hard to trace.
useEffect often masks logic that belongs in a server component, event handler, or derived state. Each use should be justified with a comment.
- Multiple separate
useState calls that change together cause re-renders and state sync bugs. Prefer a single state object.
- Custom form handling bypasses the shared validation pipeline. Use
react-hook-form + Zod to keep validation consistent.
- Building custom UI when your component library already has the component creates visual inconsistency and double maintenance. Check your component library first.
Monorepo
Commands
Architecture
Code Style
- Interfaces over types for object shapes; export all types
- Use type guards, not type assertions
- Service pattern: private class + exported factory function
- Use destructuring:
const { name } = user not const name = user.name
- Use millisecond constants (e.g.,
const TIMEOUT = 30_000) instead of magic numbers
- See
.claude/rules/coding-style.md for full style guide
Delegate to Agents
Use the Task tool to delegate tasks to specialized sub-agents. Agents are defined in .claude/agents/ — check agent descriptions to find the right one for your task.
Verification
1---2name: critical-rules-23description: CLAUDE.md Template for Next.js / Supabase / TypeScript Projects4---5<!--6CLAUDE.md Template for Next.js / Supabase / TypeScript Projects78This file provides coding standards and architecture patterns for Claude Code.910SETUP INSTRUCTIONS:111. Search for all <!-- CUSTOMIZE --> markers122. Fill in your project-specific details133. Remove examples that don't apply to your project144. Adjust rules to match your team's conventions1516This template is generalized from a production SaaS setup. Adapt as needed.17-->1819<!-- CUSTOMIZE: Replace with a brief description of your project20Example: "Acme SaaS platform — Next.js App Router, Supabase, TypeScript."21-->2223## Critical Rules2425These rules address recurring mistakes that cause real issues. Each one prevents debugging time, security vulnerabilities, or broken builds:2627- Using `any` defeats TypeScript's safety net — bugs and security issues reach production undetected. Use proper types or `unknown`.28- `console.log`/`console.error` in production breaks structured logging, making production debugging impossible. Use a proper logger (e.g., Pino, Winston, or your framework's logging utility).29- Missing `import 'server-only'` allows server code to bundle into the client, leaking API keys and database credentials to the browser.30- Server actions must validate inputs with Zod schemas and verify authentication before processing. Unauthenticated or unvalidated data must never reach the database.31- Tables without RLS expose all rows to any authenticated user — one missing policy means customer data leaks across accounts.32- Forgetting to `await params` in async server components causes runtime errors in Next.js that are hard to trace.33- `useEffect` often masks logic that belongs in a server component, event handler, or derived state. Each use should be justified with a comment.34- Multiple separate `useState` calls that change together cause re-renders and state sync bugs. Prefer a single state object.35- Custom form handling bypasses the shared validation pipeline. Use `react-hook-form` + Zod to keep validation consistent.36- Building custom UI when your component library already has the component creates visual inconsistency and double maintenance. Check your component library first.3738<!-- CUSTOMIZE: Add any project-specific or framework-specific critical rules here.39Examples:40- "When merging upstream, propagate infrastructure changes to all product apps."41- "Use your framework's Server Action wrapper for auth + validation on every mutation."42- "Never use the admin Supabase client without documenting why RLS bypass is needed."43-->4445## Monorepo4647<!-- CUSTOMIZE: List your apps/packages here, or remove this section for single-app projects. -->4849## Commands5051<!-- CUSTOMIZE: Add your project's dev, build, test, and lint commands here.5253The builder-workflow and validator-workflow skills use the following standardised command names.54Omit scripts you don't need — they're skipped automatically when not configured.5556| Command | Purpose |57|---------|---------|58| `pnpm test` | Unit tests (Vitest) |59| `pnpm test:e2e` | E2E tests (Playwright) — run for frontend phases |60| `pnpm test:db` | Database tests (PgTAP) — run for database phases |61| `pnpm run typecheck` | Type checking (`tsc --noEmit`) |62| `pnpm verify` | Full verification gate (typecheck + lint + test) |63-->6465## Architecture6667<!-- CUSTOMIZE: Describe your app's architecture (multi-tenant, data fetching, auth, type safety). -->6869## Code Style7071- Interfaces over types for object shapes; export all types72- Use type guards, not type assertions73- Service pattern: private class + exported factory function74- Use destructuring: `const { name } = user` not `const name = user.name`75- Use millisecond constants (e.g., `const TIMEOUT = 30_000`) instead of magic numbers76- See `.claude/rules/coding-style.md` for full style guide7778## Delegate to Agents7980Use the Task tool to delegate tasks to specialized sub-agents. Agents are defined in `.claude/agents/` — check agent descriptions to find the right one for your task.8182## Verification8384<!-- CUSTOMIZE: Add your project's typecheck, lint, and test commands here. -->