How to Write a Cursor Project Rule (.cursor/rules)
Cursor project rules are .mdc files with frontmatter. Learn the four rule types, which frontmatter produces each, and copy a working example.
On this page4 sections
A project rule is standing context Cursor’s agent gets without you retyping it — your conventions, your folder layout, the thing everyone gets wrong. Rules are files in the repo, so they’re reviewed and versioned like code.
1. Where rules live
Rules go in .cursor/rules/ as .mdc files. Subfolders are fine:
.cursor/rules/
react-patterns.mdc
frontend/
components.mdc
What it does: nothing until frontmatter tells Cursor when to apply each file. Plain .md
files in that folder are ignored — they have no frontmatter, so the rule system skips
them. Use .mdc.
To have Cursor scaffold one for you, type /create-rule in chat and describe what you want,
or open Customize → Rules and click Add Rule.
2. The four types
Three frontmatter fields — alwaysApply, description, globs — decide when a rule fires:
| Type | alwaysApply | description | globs |
|---|---|---|---|
| Always apply | true | — | — |
| Apply intelligently | false | set | omitted |
| Apply to specific files | false | — | set |
| Apply manually | false | omitted | omitted |
“Apply intelligently” means the agent reads the description and decides whether the rule
is relevant. “Apply manually” means it only loads when you type @rule-name in chat.
3. A rule you can paste
---
description: API route conventions for this service
globs: src/api/**/*.ts
alwaysApply: false
---
- Every route handler returns `Result<T, ApiError>`; never throw across the route boundary.
- Validate the request body with a zod schema defined in the same file, above the handler.
- Log with the shared `logger` from `@/lib/logger` — no bare `console.log` in `src/api/`.
- New routes need a test in `src/api/__tests__/` before the handler is considered done.
Follow the shape of @src/api/users/route.ts when adding a route.
What it does: attaches automatically whenever a file under src/api/ enters context, and
pulls in route.ts as a live example. The @filename reference beats pasting code into
the rule — the rule can’t go stale.
4. The simpler option
If you don’t need conditional loading, drop an AGENTS.md in the project root: plain
Markdown, no frontmatter. Nested AGENTS.md files apply inside their own directory tree,
with the more specific file taking precedence.
Next: first steps in Cursor or giving a coding agent the right context.