← Back to Payloads
tutorial

The .cursorrules File Patterns That Actually Work

Cursor's .cursorrules file is the most powerful config you're probably ignoring. Most teams write one paragraph. Here's how to write one that actually changes how the AI behaves on your codebase.
Quick Access
Install command
$ mrt install tutorial
Browse related skills

The .cursorrules File Patterns That Actually Work

If you're using Cursor and not using `.cursorrules`, you're leaving a significant performance multiplier on the table. Not a metaphor — an actual, measurable improvement in output quality when the AI understands your project's conventions. Most teams write one vague paragraph about "following existing code style" and call it done. That's the equivalent of giving a new hire a one-sentence brief and wondering why they keep breaking things.

The `.cursorrules` file is a per-directory YAML configuration that tells Cursor's model exactly how to behave on your codebase. It's not a system prompt — it's a project-level behavioral contract. Here's how to write one that actually works.

The Pattern That Most People Get Wrong

The instinct is to write generic instructions:

  • Follow the existing code style
  • Write clean, maintainable code
  • Use TypeScript best practices

This is useless. The model already knows TypeScript best practices. What it doesn't know is what your codebase specifically values — your naming conventions, your error-handling philosophy, your file organization, your team-specific patterns.

Effective `.cursorrules` files are concrete and project-specific. They replace assumptions with instructions.

Pattern 1: Enforce a Single Naming Convention

  • Use camelCase for all variable and function names
  • Use PascalCase for React component names
  • Use SCREAMING_SNAKE_CASE for environment constants
  • Prefix all async functions with "async" even when TypeScript allows omission
  • Never use abbreviated variable names (use "user" not "usr", "config" not "cfg")

Naming conventions are the single most common source of inconsistency in AI-generated code. A single explicit rule here eliminates an entire class of "fix it in review" moments.

Pattern 2: Define Your Error Handling Philosophy

  • Never swallow errors silently (no empty catch blocks)
  • All async operations must use try/catch with typed error handling
  • Throw custom error classes from errors/ directory, never raw Error
  • Every API call must have explicit error states handled in the UI layer
  • Log errors with context: logger.error('action failed', { userId, action, error })

The AI doesn't know your error-handling standards. Without explicit rules, it defaults to "throw if needed" which is usually "don't think about it." This pattern makes errors a first-class concern.

Pattern 3: Lock Down File Organization

  • Feature-based directory structure: features/{feature}/components|hooks|types|api
  • Shared UI components go in components/ui, never inside features/
  • Utility functions go in lib/, never duplicated in features/
  • Types/interfaces co-located with the code that uses them, not in a global types/ folder
  • Test files live adjacent to the code they test: Component.tsx → Component.test.tsx

AI-generated code loves to invent file locations. This pattern eliminates the "where should this go?" question entirely.

Pattern 4: Declare Your Testing Requirements

  • All new functions require unit tests in a .test.ts file
  • Use Vitest for testing framework, never Jest
  • Mock external API calls with msw, never with real network calls
  • Test file structure mirrors source: src/utils/format.ts → tests/utils/format.test.ts

-覆盖率目标: functions must have 80%+ line coverage before merge

Without this, the AI will write code and consider its job done. With it, testing becomes part of the definition of "done."

Pattern 5: Set the PR and Commit Contract

  • commits follow conventional commits: feat|, fix|, chore|, docs|
  • PR descriptions must include: what changed, why it changed, how to test
  • Never commit commented-out code — delete it and rely on git history
  • All PRs require at least one review approval before merge
  • Breaking changes must be called out explicitly in the PR title

This is useful for AI-assisted code review and commit message generation. The AI can follow your conventions if it knows what they are.

Pattern 6: TypeScript Strictness Rules

  • Enable strict mode TypeScript rules: noImplicitAny, strictNullChecks
  • Avoid any type — use unknown with type guards when the type is uncertain
  • Prefer interface over type for object shapes (easier to extend)
  • Never use @ts-ignore without a comment explaining why
  • Exported functions must have explicit return types (no type inference on boundaries)

TypeScript strictness rules eliminate entire categories of runtime errors. If your project uses strict mode, the AI needs to know.

The Meta-Pattern: Examples Over Rules

The most effective `.cursorrules` files include actual examples, not just rules:

Bad:

  • Use descriptive variable names

Good:

  • Use descriptive variable names. Example: bad → `const d = new Date()`; good → `const currentTimestamp = new Date()`

The model benefits from concrete examples more than abstract principles. When writing rules, ask: "if I was reviewing this code, would an example make this rule unambiguous?"

Organizing Large .cursorrules Files

For large projects, split rules into sections with clear headers:

=== CODE STYLE ===

  • Use TypeScript strict mode
  • No raw any types
  • ...

=== FILE ORGANIZATION ===

  • Feature-based directory structure
  • Tests co-located with source
  • ...

=== ERROR HANDLING ===

  • No silent error swallowing
  • Custom error classes required
  • ...

Clear sections make it easier to maintain and extend the rules as the project evolves.

Testing Your .cursorrules

The only way to know if your rules work: generate code and review it against the rules. If the AI violates a rule, add it to `.cursorrules`. If a rule is ambiguous, add an example. This is an iterative process — the file should evolve with your codebase.

Common sign that your rules need work: you find yourself making the same type of comment in code review repeatedly. That comment should probably be a `.cursorrules` entry.

The Bottom Line

A `.cursorrules` file is only as good as the specificity of its rules. Generic guidelines produce generic behavior. Project-specific, concrete, example-backed rules produce code that looks like it was written by someone who has been on your team for years — which is exactly what you want from an AI coding assistant.

Write the rules. Test the output. Iterate. Your code reviewers will thank you.

*Start with one section — naming conventions — and expand from there. A 20-line .cursorrules file is infinitely better than none.*