cursor lastVerified: 2026-05-08

Cursor Rules Template — .cursor/rules/*.mdc with Valid YAML Frontmatter

A copy-pasteable .cursor/rules/*.mdc template for Cursor IDE. Includes the required description / globs / alwaysApply frontmatter — not deprecated .cursorrules.

On this page
  1. Why .cursorrules is dead in 2026
  2. The template
  3. Why the three frontmatter keys matter
  4. Variants by rule scope and strictness
  5. Common pitfalls when authoring .mdc files

Why .cursorrules is dead in 2026

Until early 2025, Cursor’s project rules lived in a top-level .cursorrules plain-text file. That file format is now deprecated — Cursor’s Agent mode no longer reads it on a clean install, and emitting one in a new repository produces a silent no-op the team only notices when the rules fail to apply. The replacement is .cursor/rules/<rule>.mdc: one or more Markdown-with-frontmatter files under a dedicated directory. The frontmatter is load-bearing — it tells Cursor when to apply the rule, not just what the rule says. Three keys are required: description, globs, and alwaysApply. Miss any one and the validator at scripts/validate-templates.ts fails the build.

The template

.cursor/rules/project.mdc
---
description: Project-level rules for the Vite + React + TypeScript app
globs:
- "src/**/*.{ts,tsx}"
- "tests/**/*.{ts,tsx}"
alwaysApply: true
---

# Project rules

Cursor reads this file on every Agent-mode interaction in this repository.
Keep the body under 500 lines; the validator enforces the cap.

## Tech stack

- Vite 7 with React 19 and TypeScript 6
- Vitest 3 for unit, integration, and component tests
- Tailwind v4 utilities and daisyUI 5 classes only
- pnpm 9 as the package manager

## Locked decisions

- Path alias `@/_` resolves to `src/_` (configured in tsconfig.json and vite.config.ts).
- Component state lives in React local state; lift to context only when state crosses
three or more components.
- Styling: Tailwind utilities only. Do not introduce CSS Modules, styled-components,
or vanilla CSS files outside src/styles/.

## Hard constraints

- The TypeScript compiler runs in strict mode. Do not weaken tsconfig.json to silence
an error; fix the type instead.
- Function components only. Class components are out.
- Every `useEffect` declares every external it reads in its dependency array.
- New runtime dependencies need explicit human approval; flag and stop.

## Output Cursor must emit

1. A short paragraph naming the files Cursor will touch.
2. The unified diff per file.
3. The verification commands Cursor ran and their truncated output.
4. One sentence flagging anything intentionally left for a follow-up commit.

— lastVerified: 2026-05-08

Why the three frontmatter keys matter

description is the human-readable summary Cursor surfaces in its rules-management UI; if you omit it, the rule shows up as the file name and your colleagues cannot tell rules apart. globs is the surface area — Cursor only injects the rule into context when the active file matches a pattern in the list. A rule with globs: ["src/**/*.tsx"] skips scripts/, which is what you want for a UI rule and not what you want for a project-wide rule. alwaysApply: true overrides globs and forces the rule into every context; reserve it for rules you genuinely want loaded on every keystroke (the project-wide locked decisions, not a CSS-in-component opinion). Cursor’s rule precedence is documented behaviour: alwaysApply: true rules load first, then glob-matched rules layer on top.

Variants by rule scope and strictness

The agent-rules generator at /tools/ai-agent-rules-generator?agents=cursor emits three rule scopes crossed with three strictness levels — nine concrete combinations. The four-row table below covers the four scopes you actually use day to day.

Rule scopedescription suffixglobs examplealwaysApply
Always-apply”Project-level rules for…”["src/**/*.{ts,tsx}"]true
Glob-scoped UI”UI rules for React components”["src/components/**/*.tsx"]false
Glob-scoped tests”Vitest rules for test files”["**/*.test.{ts,tsx}"]false
Agent-only”Rules surfaced to Agent mode only”[]false

The agent-only row is a niche case: empty globs plus alwaysApply: false means the rule loads only when the user explicitly attaches it via Cursor’s @rule mention. Reserve it for rules that are genuinely opt-in — for instance, an aggressive refactor mode that you do not want firing on every save.

Common pitfalls when authoring .mdc files

Five mistakes recur. Emitting .cursorrules instead of .cursor/rules/*.mdc — the validator catches this; counter by deleting .cursorrules from any starter template you copy. Missing the closing --- delimiter on the frontmatter — Cursor parses to end-of-file and treats the whole rule body as YAML; the AGENT-07 schema in scripts/validate-templates.ts flags this explicitly. Embedding globs: syntax in your sibling CLAUDE.md because it looks similar — that field is Cursor-only; the validator’s AGENT-12 rule strips it. Forgetting alwaysApply: true on a project-wide rule — the rule still validates but the agent never sees it because no glob matches the project root file. Exceeding the 500-line body cap — break a long rule into multiple smaller .mdc files instead, each glob-scoped to its slice of the codebase. For sibling agents, see the Codex AGENTS.md template and the Claude Code bug fix prompt — the same project rule encoded for Codex and the same prompt structure encoded for Claude Code.