Cursor Rules Explained: Complete .cursor/rules Guide (2026)
SWATI BARWAL
·10 min read
Cursor rules are persistent instructions that shape how the AI writes code in your project. Without them, every chat starts from zero — the model guesses your stack, invents file paths, and reaches for libraries you do not use. With well-scoped project rules in .cursor/rules/, Cursor loads the right conventions automatically: your framework version, naming patterns, banned APIs, and testing style.
This guide explains the modern **.cursor/rules/*.mdc system (replacing the legacy `.cursorrules` file), how activation modes work, copy-paste templates for Next.js and TypeScript**, and how to keep rules from eating your context window. If you already use MCP servers in Cursor, rules complement MCP — rules define *how* to code; MCP gives the agent *live access* to tools and data.
What you'll learn
The difference between .cursorrules and .cursor/rules/*.mdc
Four rule activation modes: always, globs, agent-requested, manual
How to migrate a legacy .cursorrules file in under five minutes
Copy-paste rule templates for Next.js App Router and TypeScript APIs
Context-budget tips so rules do not slow Agent mode
How project rules interact with User Rules and MCP tools
Troubleshooting when rules are ignored or never load
Prerequisites
Cursor 0.45+ (.mdc project rules)
A project opened as a workspace root (rules apply per root folder)
Basic Markdown and optional YAML frontmatter
Optional: existing .cursorrules file to migrate
.cursorrules vs .cursor/rules — what changed
For years, developers dropped a single `.cursorrules` file in the project root. Cursor injected its contents into every prompt. That worked for small apps, but it broke down on monorepos: React rules polluted Python files, testing guidance loaded during CSS edits, and one 2,000-word file burned context on every request.
Cursor now recommends Project Rules — one or more `.mdc` files inside `.cursor/rules/`:
Approach | Location | Scoping | Agent mode | Status |
|---|---|---|---|---|
Legacy | .cursorrules | Global to project | Partial / deprecated | Still read as fallback |
Modern | .cursor/rules/*.mdc | Per-file globs + modes | Full support | Recommended |
Each .mdc file has YAML frontmatter that controls *when* the rule loads, plus a Markdown body with instructions. You can split concerns:
.cursor/rules/
├── general.mdc # Stack, naming, security (alwaysApply)
├── nextjs.mdc # App Router patterns (globs: app/**/*.tsx)
├── api-routes.mdc # Route handlers (globs: app/api/**/*.ts)
└── testing.mdc # Vitest patterns (agent-requested)Migration is quick: create .cursor/rules/, move .cursorrules content into general.mdc, add frontmatter, delete the old file. Agent mode does not load .cursorrules reliably — if you use Agent for multi-file tasks, migrate now.
Rule priority: what overrides what
Cursor merges rules from several layers (official docs):
1. Team Rules (Team/Enterprise plans) — highest priority 2. Project Rules — .cursor/rules/*.mdc, version-controlled 3. User Rules — Cursor Settings → Rules, global to your machine 4. Legacy — .cursorrules if still present 5. AGENTS.md — simple Markdown alternative in project root
Project rules win over user preferences for repo-specific conventions. Use User Rules for personal taste ("prefer concise answers") and Project Rules for team contracts ("we use pnpm, not npm").
Step 1 — Create your first .mdc rule
Create .cursor/rules/general.mdc:
---
description: Core project standards — stack, security, and git workflow
alwaysApply: true
---
# Project standards
- Package manager: pnpm (never npm or yarn)
- Language: TypeScript strict mode — no `any` without a comment
- Formatting: Prettier defaults; run `pnpm lint` before suggesting large diffs
- Security: never log secrets; never commit `.env` values; use `process.env` with validation
- Git: small focused commits; do not amend published history
- When unsure about a file path, search the repo — do not invent directories`alwaysApply: true` injects this rule on every prompt. Keep it short — under 200 words. Long always-on rules are the top cause of slow, context-starved Agent sessions.
Reload Cursor after adding rules: Command Palette → Developer: Reload Window.
Step 2 — Scope rules with globs
Stack-specific guidance should not load on every file. Use `globs` so rules attach only when relevant files are in context.
.cursor/rules/nextjs.mdc:
---
description: Next.js 15 App Router — Server Components, data fetching, metadata
globs:
- "app/**/*.tsx"
- "app/**/*.ts"
- "components/**/*.tsx"
alwaysApply: false
---
# Next.js App Router
- Default to React Server Components — add `"use client"` only when hooks or browser APIs are required
- Data fetching: use async Server Components or `fetch` with `cache: "no-store"` when data must be fresh
- Routes live under `app/` — never add Pages Router `pages/` files
- Metadata: export `generateMetadata` or static `metadata` — no `next/head` in App Router
- Images: use `next/image` with `remotePatterns` configured in `next.config.ts`
- Links: use `next/link` for internal navigationWhen you edit app/page.tsx, Cursor attaches this rule. When you edit scripts/build.ts, it does not.
Glob tips:
Use forward slashes even on Windows
Quote patterns with * in YAML lists
Prefer specific paths over **/* — overly broad globs defeat the purpose
Step 3 — Agent-requested and manual rules
Not every rule needs a glob. Two other modes exist:
Agent-requested (default when neither `alwaysApply` nor `globs` is set)
The model reads the `description` field and pulls the rule when it judges the task relevant.
.cursor/rules/database.mdc:
---
description: PostgreSQL and Drizzle ORM — migrations, queries, indexing
---
# Database rules
- Use Drizzle schema in `src/db/schema.ts`; migrations in `drizzle/`
- Every query that returns lists must paginate with explicit `LIMIT`
- Never interpolate user input into SQL — use parameterized queries
- Before adding a filter column, confirm an index exists or add a migrationThis rule stays out of context until you ask Cursor to write a query or migration.
Manual rules
Reference a rule explicitly with @ruleName in chat or set it up for on-demand loading via Cursor's rules UI. Useful for release checklists or infrequent compliance docs.
Step 4 — Migrate from .cursorrules
If your repo still has .cursorrules:
1. mkdir -p .cursor/rules 2. Create general.mdc with alwaysApply: true 3. Paste legacy content into the Markdown body below frontmatter 4. Split stack-specific sections into separate .mdc files with globs 5. Delete .cursorrules after verifying Agent mode behavior 6. Commit .cursor/rules/ to git so the team shares the same instructions
Before / after size check: if your old file was 800+ words, split it. One always-on 800-word rule costs that many tokens on *every* Agent step.
Step 5 — TypeScript API route template
.cursor/rules/api.mdc:
---
description: API route handlers — validation, errors, auth
globs:
- "app/api/**/*.ts"
- "src/app/api/**/*.ts"
---
# API route conventions
- Validate input with Zod at the top of every handler
- Return `Response.json({ error: "..." }, { status: 4xx })` — never throw unhandled errors to clients
- Auth: read session from cookies or headers in a shared `getSession()` helper
- Use `export const dynamic = "force-dynamic"` when responses must not be cached
- Log server errors with a structured logger — redact tokens and passwordsPair this with MCP servers when agents need live database or GitHub access — rules tell the model *how* to write the handler; MCP executes against real systems.
Step 6 — User Rules vs Project Rules
Layer | Where | Example |
|---|---|---|
User Rules | Cursor Settings → Rules | "Prefer minimal diffs" / "Explain trade-offs briefly" |
Project Rules | .cursor/rules/*.mdc | "This repo uses Effect-TS for services" |
Do not put secrets or environment-specific paths in User Rules if you screen-share. Project rules belong in git; user rules stay on your machine.
Context budget: rules that actually help
Every loaded rule consumes tokens. Follow these limits tested across Next.js and Node repos in July 2026:
Rule type | Target size | Activation |
|---|---|---|
Global standards | < 200 words | alwaysApply: true |
Stack / framework | 200–500 words | globs |
Deep reference (DB, auth) | 500–800 words | agent-requested |
Manual / compliance | Any | manual only |
Anti-patterns:
One mega-rule with every library version — split by domain
alwaysApply: true on framework rules — use globs instead
Pasting entire style guides — link to internal docs or use @docs
Duplicating README content — point Agent at the file with @README.md
Rules + MCP + Agent mode together
A productive Cursor setup uses three layers:
1. Rules — coding standards and architecture 2. MCP — live tools (GitHub, Postgres, filesystem sandbox) 3. Agent — multi-step execution
Example workflow:
Rule: "API routes validate with Zod and return JSON errors"
MCP: GitHub server lists open issues
Agent prompt: "Using GitHub MCP, find issues tagged api and scaffold handlers following our API rules"
Rules do not call MCP — they instruct the model how to behave *when* MCP returns data.
Team workflow: sharing rules in git
Commit .cursor/rules/ to your repository. Add a short docs/cursor-rules.md explaining how to add new rules (reviewers check for context bloat).
PR checklist for new rules:
[ ] Is alwaysApply justified, or should this be glob-scoped?
[ ] Word count under budget?
[ ] No secrets, hostnames, or personal paths?
[ ] Tested in Agent on a realistic task?
For open-source libraries, consider publishing rule packs contributors can copy into .cursor/rules/vendor/.
Step 7 — Example monorepo layout
Large repos benefit from domain-scoped rules instead of one file per language:
.cursor/rules/
├── general.mdc # alwaysApply — pnpm, TypeScript strict, security
├── frontend/
│ ├── nextjs.mdc # globs: apps/web/**
│ └── ui.mdc # globs: packages/ui/**
├── backend/
│ └── api.mdc # globs: apps/api/**
└── infra/
└── terraform.mdc # globs: infra/**/*.tfCursor reads .mdc files recursively under .cursor/rules/. Subfolders are for your organization — the AI does not treat frontend/nextjs.mdc differently from a flat file, but teams navigate rules faster during code review.
When a developer opens apps/web/app/page.tsx, both general.mdc and nextjs.mdc may load. Keep combined always-on + glob content under roughly 600 words for that workspace to stay responsive.
Step 8 — AGENTS.md as a lightweight alternative
Some projects use `AGENTS.md` in the repo root instead of (or alongside) .cursor/rules/. It is plain Markdown with no frontmatter — always on, no globs.
Use AGENTS.md when:
The team wants a single short file non-Cursor tools also read
Rules are under 30 lines and apply everywhere
You are prototyping before splitting into .mdc files
Use **.cursor/rules/*.mdc** when you need scoping, multiple domains, or fine-grained activation. Most production Next.js repos outgrow AGENTS.md within a week — plan the migration early.
Quick test after any rule change: open Agent, ask it to create a small file in the scoped directory, and confirm the output follows your conventions (imports, naming, banned APIs). If not, check Settings → Rules to verify the file is listed and the glob matches the path you edited.
Troubleshooting
Rules never seem to apply
Cause: Missing or malformed YAML frontmatter; workspace opened at a subfolder instead of repo root.
Fix: Ensure opening --- and closing --- wrap frontmatter. Open the repository root in Cursor. Reload the window after edits.
Agent ignores rules but Chat follows them
Cause: Legacy .cursorrules only — Agent mode requires .cursor/rules/*.mdc.
Fix: Migrate to .mdc files. Confirm rules appear in Cursor Settings → Rules → Project Rules.
Context window fills up immediately
Cause: Too many alwaysApply: true rules or one very long global rule.
Fix: Move framework content to glob-scoped files. Shorten global rule to security + package manager + "search before inventing paths."
Glob rule does not attach
Cause: Pattern does not match file path; wrong slashes; file outside workspace.
Fix: Test globs against paths shown in the editor tab. Use app/**/*.tsx not app/*.tsx for nested routes.
Conflicting instructions between User and Project rules
Cause: User Rules say "use tabs" while Project Rules say "use spaces."
Fix: Remove stack-specific guidance from User Rules; keep personal preference only where it does not conflict.
Rules work locally but not for teammates
Cause: .cursor/rules/ not committed; teammate on old Cursor version.
Fix: git add .cursor/rules and document minimum Cursor version in README.
FAQ
What is the difference between .cursorrules and .cursor/rules?
What does alwaysApply do in a .mdc file?
How do globs work in Cursor rules?
Does Cursor Agent mode read .cursorrules?
How long should a Cursor rule file be?
Can I use Cursor rules with Next.js and TypeScript?
Do Cursor rules replace MCP servers?
Related posts
MCP Servers in Cursor: Setup & Security Guide (2026) — wire tools after your rules define how code should look
What Is MCP? A Developer's Guide to Model Context Protocol — protocol basics behind Cursor's tool integrations
Google NotebookLM Complete Guide for Developers (2026) — research notebooks pair well with scoped project rules


