Most Cursor rules describe how a project works. "This is a Next.js app with TypeScript. We use Tailwind for styling. The API routes are in app/api." That's not a rule — that's context. Cursor already has a reasonable model of how Next.js projects work. Writing it down in a .mdc file doesn't change what it generates.
Rules that change output are different. They address the specific ways Cursor gets your project wrong, not the general structure it already understands.
Write the rule. Then look at the next 10 things Cursor generates in that context. Did any of them change? If the answer is no, the rule isn't firing.
Rules that tend not to fire: anything describing technology choices Cursor already assumes for the stack ("use TypeScript"), anything describing general best practices ("write clean, readable code"), anything that's just naming the project structure.
Rules that tend to fire: explicit prohibitions, specific naming patterns that deviate from defaults, tool choices that contradict Cursor's assumptions for the stack.
Cursor follows prohibitions more reliably than preferences. "Never use axios" sticks better than "prefer fetch over axios." This is the same principle as CLAUDE.md rules — preference language is optional, prohibition language is not.
# Fires reliably:
Never use axios. Use native fetch with this pattern:
const res = await fetch(url, { headers, ... });
if (!res.ok) throw new Error(`${res.status}`);
# Often ignored:
Prefer native fetch over axios when possible.
The version with the actual fetch pattern does double duty: it tells Cursor what not to do and gives it the specific replacement. Without the replacement pattern, even a clear prohibition sometimes produces: "I can't use axios, so let me use node-fetch" or something else you didn't want.
Every framework has defaults that Cursor's training assumed are fine but that your project does differently. Those are where rules pay off.
For Next.js: Cursor defaults to the Pages Router in many completions even when you're on App Router. A rule that says "this project uses App Router — never create files under pages/" will fire constantly because this is a real deviation from a common assumption.
For Python: Cursor often uses print() for debug output. If your project uses structured logging (logger.info()), a rule that says "never use print() in this project — use logger from app/logging.py" will change a lot of generated code.
For any project with an ORM: Cursor will sometimes write raw SQL when an ORM query would be correct for your stack. A rule that specifies which ORM and which query patterns to use saves you from correcting that repeatedly.
Cursor loads .mdc rules based on glob patterns. A rule in .cursor/rules/global.mdc runs on everything. A rule in .cursor/rules/api.mdc with a glob of app/api/** runs only when you're working in that directory.
Global rules should be short — maybe 10-15 items covering true cross-project constraints. If you have 40 global rules, they're too long to all get useful attention. Scoped rules can be more verbose because they only fire in the relevant context.
Most projects benefit from: one global file with project-wide prohibitions, one or two stack-specific files (frontend, backend), and per-directory rules for unusual patterns in specific parts of the codebase.
Watch your edits for a week. Every time you correct something Cursor generated — a wrong import, a banned function, an incorrect pattern — write a rule that would have prevented it. After a week you'll have 5-10 rules that are actually relevant to your project, instead of 40 that describe how React works.
The Cursor Rules Starter Pack has project-type-specific .mdc files for Next.js, Python CLI, Node API, React Native, and MCP servers — with the specific prohibitions and patterns that change Cursor's output for each stack. $19 at Payhip.