Cursor rules are persistent instructions that customize how Cursor's AI agent behaves. Instead of repeating the same preferences in every chat message — "use TypeScript interfaces, not types" or "always write tests with Vitest" — you write a rule once and Cursor follows it automatically.
Rules live in your project's .cursor/rules/ directory as .mdc files (markdown with YAML frontmatter). They replace the deprecated .cursorrules root file with a more flexible system that supports conditional activation, file-pattern matching, and team sharing via version control.
Important: Cursor rules only affect the Agent (Chat). They do not affect Tab autocomplete or Inline Edit (Cmd/Ctrl+K).
Cursor supports four rule activation modes, controlled by the frontmatter fields you set:
| Type | Frontmatter | When it activates |
|---|---|---|
| Always Apply | alwaysApply: true | Every conversation, unconditionally |
| Auto | description present, no globs | Agent reads the description and decides if it's relevant |
| Glob-matched | globs: ["**/*.tsx"] | When conversation involves files matching the pattern |
| Manual | No description, no globs, alwaysApply: false | Only when you type @ruleName in chat |
When to use each:
.tsx, SQL conventions for .sql, test patterns for *.test.*)Each rule is an .mdc file in .cursor/rules/ with YAML frontmatter and a markdown body:
---
description: "React component conventions using TypeScript interfaces and functional components"
alwaysApply: false
globs: ["**/*.tsx", "**/*.jsx"]
---
# React Component Conventions
## Structure
- Use functional components with arrow function syntax
- Define props using TypeScript interfaces (not type aliases)
- Use named exports, not default exports
## Example
\`\`\`tsx
interface ButtonProps {
label: string;
onClick: () => void;
variant?: "primary" | "secondary";
}
export const Button = ({ label, onClick, variant = "primary" }: ButtonProps) => {
return (
<button className={variant} onClick={onClick}>
{label}
</button>
);
};
\`\`\`
Frontmatter fields:
| Field | Type | Purpose |
|---|---|---|
description | string | Tells the agent what this rule covers — used for Auto activation |
alwaysApply | boolean | If true, loaded on every conversation |
globs | string or string[] | File patterns that trigger this rule |
Folders inside .cursor/rules/ are purely for your organization — Cursor flattens the structure when loading rules.
mkdir -p .cursor/rules
Create a new file — for example, .cursor/rules/coding-style.mdc:
---
description: "Project coding style and conventions"
alwaysApply: true
---
# Coding Style
- Use 2-space indentation
- Use single quotes for strings
- Add trailing commas in multi-line arrays and objects
- Prefer const over let; never use var
- Use early returns to reduce nesting
This rule applies to every conversation because alwaysApply: true.
The difference between a useful rule and a wasted one comes down to specificity.
Good rules are:
| Quality | Bad example | Good example |
|---|---|---|
| Specific | "Write clean code" | "Use 2-space indentation, single quotes, trailing commas" |
| Actionable | "Follow best practices" | "Every async function must have a try/catch with typed error handling" |
| Example-rich | "Use proper naming" | "Variables: camelCase. Components: PascalCase. Constants: UPPER_SNAKE_CASE. Example: const MAX_RETRIES = 3" |
| Focused | One file covering everything | One file per topic: react.mdc, testing.mdc, api.mdc |
Best practices:
After creating a rule, verify it works:
For Always Apply rules: Start a new chat and ask the agent to write code. Check that it follows your conventions without being told.
For Auto rules: Describe a task that matches the rule's description. The agent should pick up the rule automatically. If it doesn't, make the description more specific.
For Glob-matched rules: Open or reference a file that matches the glob pattern, then ask the agent to modify it. Verify it follows the file-type-specific conventions.
For Manual rules: Type @rule-name in chat and confirm the agent acknowledges and follows the rule's instructions.
If a rule isn't activating, check: Is the file in .cursor/rules/? Does the frontmatter parse correctly (valid YAML)? For glob rules, does the pattern match your files?
When multiple rules apply, Cursor merges them with this priority order:
| Level | Location | Managed by |
|---|---|---|
| Team | Cursor dashboard | Admins (Team/Enterprise plans) |
| Project | .cursor/rules/ in repo | Developers via git |
| User | Cursor Settings > Rules | Individual preference |
Higher-priority rules win when there are conflicts. In practice, commit project rules to .cursor/rules/ in your repo so the whole team shares them, and use personal User rules for individual preferences like verbosity or language.
Here are the most common types of rules developers create:
Multiple systems exist for giving AI agents persistent instructions. Here's how they compare:
| System | Format | Works in | Activation |
|---|---|---|---|
| Cursor Rules | .mdc in .cursor/rules/ | Cursor only | Always, Auto, Glob, Manual |
| Skills | SKILL.md in .claude/skills/ | 30+ tools (Claude Code, Cursor, VS Code, Windsurf, Codex, etc.) | Auto + slash command |
| AGENTS.md | Plain markdown in project root | Multiple editors | Always loaded |
When to use each:
Many rules on Machina are available in both Cursor and Skills formats.
.cursor/rules/ to your repo. Every team member gets the rules automatically.There's no hard limit on the number of rule files. However, every active rule consumes context tokens. Use Always Apply sparingly (only for truly universal conventions) and prefer Auto or Glob-matched rules that load only when relevant.
No. Cursor rules only affect the Agent (Chat). Tab autocomplete and Inline Edit (Cmd/Ctrl+K) do not read rules. If you need consistent autocomplete behavior, that's controlled by Cursor's model settings, not rules.
Yes. The content is compatible — both are markdown with YAML frontmatter. Change the frontmatter fields to the Skills format (name and description), rename the file to SKILL.md, and place it in .claude/skills/. See the Getting Started with Skills tutorial for the full format.
Use folders within .cursor/rules/ for logical grouping (e.g., frontend/, backend/, testing/). Cursor ignores the folder structure when loading rules, so this is purely for human readability. Prefer many focused rules over one massive file — it's easier to maintain, review, and selectively activate.