Cursor Rules Explained: .cursor/rules and .cursorrules (2026)
Cursor rules are version-controlled instructions that shape how the Agent edits your code. Here is the current .mdc format, how it differs from the old .cursorrules file, and ready-to-use rules for common stacks.
Cursor rules are .mdc files that live in your repo and steer the Agent's behavior. Unlike a setting buried in the app, they are version-controlled, reviewable, and shared with your whole team. The official Rules docs define the full frontmatter spec.
The four scopes
The thing most people get wrong is scope. A rule that fires on every file when it should fire on three files just burns context and confuses the model. Each rule has frontmatter that controls when it applies.
---
description: Conventions for HTTP route handlers
globs: src/routes/**/*.ts
alwaysApply: false
---
- Every handler validates input with zod before use.
- Return the ApiResponse<T> envelope, never a raw object.
- Errors throw AppError; do not return error shapes by hand.alwaysApply: trueapplies the rule on every request. Reserve it for a tiny set of global laws.globsattach the rule only when matching files are in play. This is the workhorse.descriptionlets the Agent pull the rule in on demand when the task seems relevant.- A manual mode where the rule only loads if you reference it explicitly.
The new format vs the old .cursorrules file
The current format is one .mdc file per rule under .cursor/rules/, each with its own scope. The older approach was a single .cursorrules file at the repo root holding every instruction as plain text. Cursor still reads that file for backward compatibility, so old projects keep working, but the recommended format is the scoped .mdc files. If you have a legacy file, you can migrate by splitting it into a few scoped rules.
# Older single-file format. Works, but everything is always on.
- Use TypeScript strict mode, no any.
- Prefer named exports.
- Write tests with Vitest.Real rules for common stacks
Here are three rules you can drop into .cursor/rules and trim to taste. Each is scoped so it only loads when it is relevant, which keeps the Agent's context clean.
---
description: Next.js App Router and React component conventions
globs: app/**/*.tsx, components/**/*.tsx
alwaysApply: false
---
- Default to Server Components. Add "use client" only when a component needs state, effects, or browser APIs.
- Data fetching happens in Server Components or route handlers, never in useEffect.
- Co-locate a component with its styles and tests; one folder per feature.
- Use the next/image and next/link components, not raw <img> or <a> for internal navigation.---
description: Python style and typing conventions
globs: **/*.py
alwaysApply: false
---
- Target Python 3.12. Add type hints on every function signature.
- Format with ruff; keep functions small and pure where possible.
- Raise specific exceptions, never a bare except. Log with the logging module, not print.
- Tests use pytest and live in tests/ mirroring the package layout.---
description: Project-wide laws that apply to every file
alwaysApply: true
---
- Never commit secrets. Read config from environment variables.
- Match the surrounding code style; do not reformat unrelated lines.
- When unsure about intent, ask before making a large change.Steal good rules
You do not have to write rules from scratch. The community has curated thousands of them by framework and language. Grab one close to your stack and trim it down.
PatrickJS/awesome-cursorrulesThe most comprehensive collection of rule files, categorized by framework and language.github.com32kCursor DirectoryBrowse the best rules by framework, with an auto-generator that scans your repo.cursor.directory
28:05FAQ
Where do Cursor rules live?
Project rules go in .cursor/rules/ as .mdc files, committed with your code. Personal rules that follow you across every project live in Cursor under Customize, Rules. Plain .md files in the rules folder are ignored, so the extension has to be .mdc.
Does the old .cursorrules file still work?
Yes. Cursor still reads a single .cursorrules file at the repo root for backward compatibility, so existing projects keep working. It is the legacy format though; new projects should use scoped .mdc files under .cursor/rules/ so rules load only when they are relevant.
How do I stop a rule from applying to every file?
Set alwaysApply: false and add a globs line so the rule only attaches when matching files are open, for example globs: app/**/*.tsx. Reserve alwaysApply: true for one small file of project-wide laws.
Cursor rules or AGENTS.md?
Both work. Cursor also reads nested AGENTS.md files in subdirectories, applied automatically when you work on files under them, which is handy in a monorepo. Use .cursor/rules when you want glob scoping and the four apply modes; use AGENTS.md when you want one shared instruction file per package.
0 Comments
Loading discussion...