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 Guides
guide
best-practices

How to Write AI Coding Rules for Cursor, Claude Code, and Copilot

Ten battle-tested principles for writing AI coding rules that actually work — with before/after examples, anti-patterns to avoid, and templates for .cursorrules, CLAUDE.md, and copilot-instructions.md.

Agent Rules Team2/18/20267 min read

Writing good agent rules is a skill, not a given. Done well, a rules file makes your AI assistant feel like a senior developer who already deeply knows your codebase. Done poorly, it becomes ignored noise that doesn't improve output at all.

The right mental model: you're writing instructions for an incredibly capable engineer who has read every programming book but has never seen your project. They know all the patterns — but they don't know which ones you've chosen, why, or which tradeoffs you've already resolved. Your job is to answer those questions upfront.


1. Start with a One-Paragraph Project Brief

Before any rules, give the AI a brief description of what the project actually is. This frames every decision that follows.

Ineffective:

markdown
# My Project

Effective:

markdown
# Project: Acme CRM

You are a senior TypeScript engineer working on Acme CRM — a customer relationship management platform for mid-sized B2B companies. The frontend is Next.js 15 App Router, the API is Fastify on Node.js 22, and everything shares a PostgreSQL database via Drizzle ORM. The product has 50,000+ active users in production.

"50,000+ users in production" signals the AI to prioritize correctness and backward compatibility over bleeding-edge patterns. Context changes decisions.


2. Declare Your Exact Tech Stack with Versions

The single most impactful section in any rules file. AI models contain knowledge of multiple incompatible versions of the same library. Without version pins, they guess — and guess inconsistently.

Vague:

markdown
- React, TypeScript, testing library

Precise:

markdown
## Tech Stack
- React 18.3 (not 19 — do not use React 19 APIs like `use()` or `useOptimistic`)
- TypeScript 5.4 (strict mode, exactOptionalPropertyTypes: true)
- Next.js 15.1 App Router only (no Pages Router patterns)
- Tailwind CSS v4 (no tailwind.config.js — uses CSS-based config)
- Drizzle ORM 0.30 (use `db.query` API, not raw SQL strings)
- Vitest 2.x + React Testing Library 16.x

The parenthetical notes are crucial — they pre-answer follow-up questions the AI would otherwise guess at.


3. Lead with Critical, Non-Negotiable Rules

AI models pay more attention to content near the top of a document. Put your hard constraints first, using emphatic language.

markdown
## Critical Rules — Always Follow
- NEVER use `any` type — use `unknown` with type guards or define interfaces
- NEVER use `getServerSideProps` — this project uses App Router only
- NEVER commit secrets or API keys
- ALWAYS validate user input with Zod at every API boundary
- ALWAYS wrap database calls in try/catch with typed error handling

The ALL-CAPS "NEVER" and "ALWAYS" phrasing isn't just emphasis style — it meaningfully improves rule adherence in practice.


4. Write Negative Instructions — They're Just as Important

Every AI model has fallback patterns it uses when not told otherwise. Explicitly name what you don't want to override those defaults.

Too vague: "Write good TypeScript."

Precise:

markdown
TypeScript rules:
- No `any` type under any circumstances
- No type assertions (`as`) unless required for DOM narrowing
- No non-null assertions (`!`) — handle nullability explicitly
- Use discriminated unions for state, not boolean flags

Common high-value negative instructions:

  • "Never use useEffect for data fetching — use React Query or Server Components"
  • "Never write comments that restate what the code does — only explain non-obvious logic"
  • "Never use console.log in production — use logger from @/lib/logger"
  • "Never install new packages without noting the addition in your response"

5. Show One Example Per Key Convention

A single good code example conveys more than paragraphs of prose. Use the format: "When doing X, follow this exact structure:"

markdown
## Component Pattern

When creating UI components, always use this structure:
tsx
import { type FC } from "react";

interface UserCardProps {
  name: string;
  email: string;
  onSelect: (id: string) => void;
}

export const UserCard: FC<UserCardProps> = ({ name, email, onSelect }) => {
  return (
    <div className="rounded-lg border border-border p-4">
      <p className="font-semibold">{name}</p>
      <p className="text-sm text-muted-foreground">{email}</p>
      <button type="button" onClick={() => onSelect(email)}
        className="mt-3 text-sm font-medium text-brand hover:underline">
        Select
      </button>
    </div>
  );
};

Rules demonstrated through example are harder to misinterpret and easier for the model to extend to new situations.


6. Describe Your File Structure (Briefly)

Tell the AI where things live — it will choose correct import paths and ask fewer clarifying questions.

markdown
## File Structure
- `app/` — Next.js App Router pages and layouts
- `components/ui/` — shadcn/ui primitives (never modify directly)
- `components/` — feature-specific composite components
- `lib/` — shared utilities, constants, type definitions
- `server/` — server-only code: DB queries, server actions
- `hooks/` — custom React hooks (client-side only)
- Import alias: `@/` maps to the project root src/

Keep it brief — convey conventions, not a file inventory.


7. Specify Your Error Handling Pattern

AI-generated code skips error handling by default. An explicit pattern prevents this.

markdown
## Error Handling
- All async functions must be wrapped in try/catch
- Use the `AppError` class from `@/lib/errors` for typed application errors
- API routes return errors in this format: { error: { code, message }, status }
- Never use empty catch blocks — always log or re-throw
- Use `logger.error()` from `@/lib/logger` for server-side errors

8. Set Testing Expectations

Without testing requirements, AI-generated code rarely includes tests. When it does, they often test implementation details rather than behavior.

markdown
## Testing
- Framework: Vitest + React Testing Library
- Pattern: Arrange-Act-Assert inside describe/it blocks
- Mock external calls with `vi.mock()`
- Test user-visible behavior, not internal component state
- Every utility function needs: one happy path test + one error case test
- E2E tests live in `e2e/` using Playwright

9. Order Sections by Priority

AI models apply more attention to content at the beginning and end of a document. Structure accordingly:

  1. Project brief — sets the frame
  2. Critical rules — must-follow constraints
  3. Tech stack — version pins
  4. Code style — naming, formatting
  5. File structure — import paths
  6. Error handling — error patterns
  7. Testing — framework and requirements
  8. Secondary preferences — documentation, commits

10. Iterate: Rules Are Living Documentation

Your rules file should grow every time you correct the AI for the same mistake twice. Treat corrections as feedback:

  • Wrong import path → add an import convention rule
  • Old API usage → add a version constraint
  • Missing error handling → strengthen the error section
  • Wrong library → specify preferred library + a "don't use X" prohibition

The most effective rules files are built over months of real AI-assisted development. They accumulate the collective wisdom of every correction your team has made.


Complete Template

markdown
# Project: [Name]

You are a senior [language] engineer working on [description].
The codebase is in production serving [X] users.

## Critical Rules
- NEVER [most important constraint]
- ALWAYS [most important requirement]

## Tech Stack
- [Framework] [version] ([key note])
- [Language] [version] ([config])
- [Database] ([usage pattern])
- [Auth] ([how it works])
- [Testing] ([framework + pattern])

## Code Style
- [Export convention]
- [Component/module pattern]
- [Naming conventions]

## File Structure
- `[dir]/` — [purpose]
- Import alias: `@/` → [maps to]

## Error Handling
- [Pattern for async errors]
- [Error response format]

## Testing
- [Framework and pattern]
- [What must be tested]
Previous
Cursor Rules vs CLAUDE.md vs Copilot Instructions — Which to Use?
Next
Agent Rules Best Practices: How to Write Rules That Actually Work

Explore Rules by Language

TypeScript Agent RulesPython Agent RulesGo Agent RulesRust Agent RulesJavaScript Agent RulesJava Agent Rules→ All Languages