The old .cursorrules file at your project root is deprecated. Cursor still reads it, but the deprecation warning is there for a reason. The new system --- .mdc files in .cursor/rules/ --- is better in every way that matters: scoped activation, glob patterns, lower token cost, and rules that only load when they're relevant.
Most developers are either still using the legacy format or haven't configured rules at all. Both waste the most powerful leverage point Cursor offers: teaching it how your specific project works.
Here are production-tested rules for every major tech stack, the new .mdc format explained, and the eight mistakes that make Cursor ignore your instructions.
Key Takeaways
.cursorrulesis deprecated. Move to.cursor/rules/*.mdcfiles with frontmatter-based activation.- The new format has four activation types: Always, Auto-Attached (globs), Agent-Requested (description), and Manual (@mention)
- Scoped rules save tokens --- only relevant rules load into context, not everything at once
- cursor.directory and awesome-cursorrules (38.7K stars) are the community's best rule sources
- The #1 mistake: rules too long. Critical instructions get lost in the middle. Keep each rule file focused.
Short Answer
What should I do? Create a .cursor/rules/ directory. Add focused .mdc files with proper frontmatter --- one for general conventions (alwaysApply: true), others scoped by glob pattern (*.tsx, /api/, *.test.ts). Keep each file under 200 lines. Migrate your old .cursorrules content into this structure. Delete the legacy file.
The New Format: .mdc Files
The .mdc (Markdown with Components) format adds a YAML frontmatter header to markdown rules. This header controls when and how the rule activates.
Directory Structure
project-root/
├── .cursor/
│ └── rules/
│ ├── general.mdc # alwaysApply: true
│ ├── react-components.mdc # globs: **/*.tsx, **/*.jsx
│ ├── api-routes.mdc # globs: **/api/**/*.ts
│ ├── testing.mdc # globs: **/*.test.ts, **/*.spec.ts
│ └── database.mdc # globs: **/db/**, **/models/**
└── src/
Frontmatter Fields
---
description: Short description of what this rule covers
globs: **/*.tsx, **/*.jsx
alwaysApply: false
---
# Your rules in markdown here
Four Activation Types
| Type | alwaysApply | globs | description | When It Loads |
|---|---|---|---|---|
| Always | true |
empty | optional | Every conversation |
| Auto-Attached | false |
pattern set | optional | When matching files are in context |
| Agent-Requested | false |
empty | required | AI reads description, decides if relevant |
| Manual | false |
empty | optional | Only when you type @rulename |
Use "Always" sparingly --- only for conventions that apply to every file in the project. Use "Auto-Attached" with globs for everything else. This keeps your context lean.
Production Rules by Tech Stack
React / Next.js / Tailwind
File: .cursor/rules/react-nextjs.mdc
---
description: React and Next.js conventions for this project
globs: **/*.tsx, **/*.jsx, **/app/**/*.ts
alwaysApply: false
---
You are an expert in TypeScript, Next.js 15 App Router, React 19, and Tailwind CSS 4.
Key Principles:
- Use functional components with TypeScript interfaces
- Use Server Components by default, 'use client' only when needed
- Prefer named exports for components
- Use lowercase-with-dashes for directories (components/auth-wizard/)
- Descriptive variable names with auxiliary verbs (isLoading, hasError)
Component Patterns:
- Props as TypeScript interfaces, not type aliases
- Prefer composition over prop drilling
- Use Suspense boundaries for async components
- Error boundaries on route segments
Styling:
- Tailwind CSS utility classes only, no CSS modules
- Use cn() utility for conditional classes
- Mobile-first responsive design
- Design tokens via CSS custom properties
Next.js Specifics:
- generateMetadata for all public pages
- next/image for all images
- Route handlers in app/api/ with proper error responses
- Parallel routes and intercepting routes where appropriate
NEVER:
- Use class components
- Use default exports for components
- Use inline styles
- Use CSS-in-JS libraries
- Import from 'react' (auto-imported in React 19)
Python / FastAPI
File: .cursor/rules/python-fastapi.mdc
---
description: Python and FastAPI conventions
globs: **/*.py
alwaysApply: false
---
You are an expert in Python 3.12+, FastAPI, and scalable API development.
Key Principles:
- Type hints on ALL function signatures
- Pydantic v2 BaseModel for all request/response schemas
- async def for database and external API operations
- def for pure computation functions
- File naming: lowercase with underscores (routers/user_routes.py)
FastAPI Patterns:
- Dependency injection for state management and auth
- Router-level dependencies for shared middleware
- Background tasks for non-blocking operations
- Proper status codes (201 for created, 204 for deleted)
Error Handling:
- Custom exception handlers, not bare try/except
- HTTPException with detail messages for API errors
- Structured error responses: {"detail": "message", "code": "ERROR_CODE"}
Performance:
- Async database drivers (asyncpg, motor)
- Connection pooling via dependencies
- Redis caching for expensive operations
- Lazy loading for large datasets
NEVER:
- Use raw dicts where Pydantic models work
- Use synchronous database calls in async routes
- Catch broad exceptions without logging
- Store secrets in code or config files
Go
File: .cursor/rules/golang.mdc
---
description: Go conventions and patterns
globs: **/*.go
alwaysApply: false
---
You are an expert in Go 1.22+, using the standard library where possible.
Project Layout:
- cmd/ for entry points
- internal/ for private packages
- pkg/ for public libraries
- api/ for OpenAPI specs
Key Principles:
- Short, focused functions with single responsibility
- Always handle errors explicitly; wrap with fmt.Errorf("context: %w", err)
- Accept interfaces, return structs
- Table-driven tests with t.Parallel()
- GoDoc comments on all public functions
Patterns:
- Context propagation for cancellation and timeouts
- Middleware for cross-cutting concerns (logging, auth, tracing)
- Functional options pattern for configurable constructors
- Graceful shutdown with signal handling
Naming:
- CamelCase for exports, camelCase for private
- Receiver names: single letter matching type (func (s *Server))
- Interface names: -er suffix when possible (Reader, Writer)
NEVER:
- Use init() functions (explicit initialization instead)
- Ignore error returns
- Use global state or package-level variables for mutable state
- Use panic for recoverable errors
TypeScript Strict
File: .cursor/rules/typescript-strict.mdc
---
description: TypeScript strict mode conventions
globs: **/*.ts, **/*.tsx
alwaysApply: false
---
TypeScript Rules (strict: true):
- noImplicitAny, strictNullChecks, exactOptionalPropertyTypes enabled
- Use interface over type for object shapes (better errors, extendable)
- Prefer const assertions and satisfies operator
- Use discriminated unions over optional fields for variants
- No any --- use unknown + type guards instead
- Exhaustive switch with never checks
- Use branded types for IDs: type UserId = string & { __brand: 'UserId' }
Patterns:
- Zod schemas for runtime validation at boundaries
- Infer types from schemas: type User = z.infer<typeof userSchema>
- Generic constraints over type assertions
- Narrowing with in, instanceof, and custom type guards
NEVER:
- Use any (use unknown)
- Use @ts-ignore (use @ts-expect-error with explanation)
- Use non-null assertion (!) without documented justification
- Use enums (use const objects with as const)
The General Rules File
Every project needs one "always on" rule file for project-wide conventions:
File: .cursor/rules/general.mdc
---
description: Project-wide conventions and commands
alwaysApply: true
---
# Project: [Your Project Name]
Tech Stack: [framework] [version], [language], [database], [hosting]
Commands:
- Test single file: [your test command]
- Type check: [your typecheck command]
- Build: [your build command]
- Lint: [your lint command]
Git:
- Branch naming: feature/, fix/, chore/
- Conventional commits (feat:, fix:, chore:)
CRITICAL:
- ALWAYS run typecheck after modifying TypeScript files
- NEVER commit .env files or credentials
- NEVER use console.log in production code
Keep this under 50 lines. Everything else goes in scoped rule files.
Testing Rules
File: .cursor/rules/testing.mdc
---
description: Testing conventions and patterns
globs: **/*.test.ts, **/*.test.tsx, **/*.spec.ts, **/__tests__/**
alwaysApply: false
---
Testing Framework: [Jest/Vitest/Playwright]
Principles:
- Test behavior, not implementation
- One assertion concept per test (multiple expects are fine if testing one behavior)
- Descriptive test names: "should [expected behavior] when [condition]"
- Arrange-Act-Assert structure
Patterns:
- Factory functions for test data, not raw object literals
- Mock at boundaries (API calls, database), not internal functions
- Integration tests for API routes, unit tests for pure logic
- Snapshot tests only for serializable output, never for components
NEVER:
- Test private methods directly
- Use random data without seeds
- Leave .only() or .skip() in committed tests
- Mock modules you own (refactor instead)
Migrating from .cursorrules
If you have an existing .cursorrules file:
- Create
.cursor/rules/directory - Split your monolithic file into focused
.mdcfiles by concern - Add frontmatter to each file with appropriate activation
- Move framework-specific rules to glob-matched files
- Keep only truly universal rules in
alwaysApply: true - Delete the old
.cursorrulesfile
The migration is worth the effort. A single 300-line .cursorrules file loads into every conversation, consuming ~2,000 tokens. Five scoped .mdc files load only when relevant, typically consuming 400-800 tokens per conversation. That's 60-80% fewer tokens spent on instructions.
The Eight Mistakes
1. Rules Too Long
The #1 failure. Research shows AI models remember instructions at the beginning and end but forget the middle. A 200-line rule file means your critical conventions in the middle get ignored. Keep each .mdc file under 100 lines.
2. Vague Instructions
"Write clean code" and "prefer good patterns" get completely ignored. Be concrete: "Use Pydantic v2 BaseModel for all request/response schemas" works. "Write good schemas" doesn't.
3. Not Splitting Rules
One massive file wastes tokens. Split by concern (components, API, testing, database) with proper globs. Only relevant rules load, saving context for actual code.
4. Conflicting with the Codebase
If your codebase uses pattern A but rules say pattern B, Cursor follows the codebase. Either update rules to match reality or refactor the code to match the rules. Contradictions waste tokens and produce inconsistent output.
5. Outdated Rules
Specifying Next.js 13 patterns when your project uses Next.js 15 causes confident generation of deprecated code. Keep rules in sync with your dependencies.
6. Malformed Frontmatter
Missing alwaysApply field, broken YAML syntax, or glob patterns that match nothing. Rules silently fail. Test by checking if Cursor follows them on a matching file.
7. Rules Forgotten Mid-Conversation
After many messages, Cursor's context optimization may push rules out. Starting fresh conversations for new features helps. For critical rules, saying "remember the project rules" can re-anchor them.
8. Over-Specifying Globally
20 global alwaysApply: true rules add approximately 2,000 tokens to every single message. That's context budget taken from actual code. Be ruthless about what truly needs to be always-on.
Debugging tip: If Cursor behaves strangely, temporarily move .cursor/rules/ to a backup location. If behavior improves, you have rule overload. Add rules back one at a time to find the conflict.
Where to Find More Rules
- cursor.directory --- Community-maintained library, browseable by framework
- awesome-cursorrules --- 38,700+ GitHub stars, the largest collection
- cursorrules.org --- AI-powered rule generator
- Cursor's
/Generate Cursor Rulescommand --- Analyzes your codebase and generates starter rules
Cursor Rules vs CLAUDE.md vs AGENTS.md
| Feature | Cursor .mdc |
CLAUDE.md | AGENTS.md |
|---|---|---|---|
| Format | YAML frontmatter + Markdown | Plain Markdown | Plain Markdown |
| Activation | 4 types (Always, Auto, Agent, Manual) | Always loaded | Always loaded |
| Glob patterns | Yes (frontmatter) | No native globs | No |
| File imports | @file references |
@path imports |
No |
| Scoping | Per-file-type, per-directory | Project + directory level | Project level |
| Multi-tool | Cursor only | Claude Code only | Multi-tool compatible |
If your team uses multiple AI tools, maintain both Cursor rules and CLAUDE.md (or AGENTS.md). Tools like rule-porter can convert between formats. For a deep dive on Claude Code configuration, see our post on the CLAUDE.md playbook.
FAQ
Should I commit .cursor/rules/ to git?
Yes. Project rules are team conventions that should be shared. Personal preferences go in Cursor Settings > General > Rules for AI (not version controlled).
Do .cursorrules still work?
Yes, but they show a deprecation warning. Cursor still reads them, but the recommendation is to migrate to .cursor/rules/*.mdc. No hard removal date has been announced.
How many rule files should I have?
3-7 for most projects. One general (always-on), plus scoped files for your main concerns: components, API, testing, database, styling. More than 10 suggests you're over-engineering rules.
Can I use @file references inside rules?
Yes. @path/to/file inside a rule body references another file. Useful for pointing to examples or schemas without embedding them in the rule.
Do rules work in Cursor's Agent mode?
Yes. Agent mode reads all applicable rules before starting work. Auto-Attached rules activate based on the files the agent touches.
Key Takeaways
- Migrate to .mdc format --- scoped activation and glob patterns save 60-80% of token overhead versus a monolithic
.cursorrules - Split rules by concern --- one file per domain (components, API, testing), not one file for everything
- Be specific, not aspirational --- "Use Pydantic v2 BaseModel" beats "write clean code"
- Keep each file under 100 lines --- critical instructions in the middle of long files get ignored
- The ecosystem has your back --- cursor.directory, awesome-cursorrules (38.7K stars), and the
/Generate Cursor Rulescommand give you a head start
Further reading: The CLAUDE.md Playbook: 12 Rules That Work | Context Window Mastery