All articles

Cursor Rules Explained: Complete .cursor/rules Guide (2026)

SWATI BARWAL

SWATI BARWAL

·10 min read

cursor

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:

Code
.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:

Markdown
---
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:

Markdown
---
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 navigation

When 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:

Markdown
---
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 migration

This 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:

Markdown
---
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 passwords

Pair 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:

Code
.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/**/*.tf

Cursor 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

SWATI BARWAL

Written by

SWATI BARWAL

1 follower

Related posts