Back to Research

The Cursor rules that are worth writing

Most Cursor rules files are too long to work. Here is what to keep, what to delete, and how to tell whether a rule changed the output.

Henri-edmon cross, mandorli in fiore, 1902, MIN 1898, 02, landscape painting by Henri-Edmond Cross (1902).
Rogier MullerAugust 15, 20264 min read

Write rules the way you would brief a contractor

Cursor rules are instructions loaded into the agent's context from files under .cursor/rules/. The useful test for any line you are about to add: would you say this to a competent contractor on their first day, and would they be able to act on it? If yes, keep it. If it is a value statement, delete it.

"Write clean, maintainable code" fails the test. Nobody was planning to write dirty code. "Database access goes through the repository layer in src/db/. Handlers never import the client directly" passes, because it can be violated by a specific import line and checked in review.

What belongs in a Cursor rules file

  • The commands. How to run tests, the type checker, and the dev server. Name them exactly.
  • Boundaries. Which directories are generated, vendored, or off limits.
  • Decisions with a stated reason. "We use dates as ISO strings at the API boundary, never Date objects, because two client teams parse them."
  • Local precedents to copy. "New endpoints follow the shape of src/api/orders.ts."
  • Anti-patterns you keep having to correct. If you have said it in review twice, it is a rule.

What does not belong: anything the linter already enforces, anything visible from reading two neighbouring files, and general programming advice. The agent already knows what a pure function is. Spending context to tell it wastes attention that your actual conventions needed.

Scope beats length

The most common broken setup we see is a single always-applied rules file that has grown to several hundred lines over six months. The team's complaint is always the same: it used to follow the rules and now it ignores them. That is exactly what happens when the instruction block gets long enough that no single line stands out.

Split it. Each rule file gets frontmatter with a globs pattern so it only loads when relevant files are in play:

---
description: API handler conventions
globs: ["src/api/**/*.ts"]
---
Validate input with the zod schema in the same directory before touching the database.
Return errors through the ApiError helper, never a bare throw.

Keep the always-on file to the handful of facts that are true everywhere. Twenty lines is a reasonable ceiling. Everything else is scoped.

How to tell whether a rule is doing anything

Do not trust the vibe. Run the same task twice, once with the rule and once with it disabled, on a fresh session both times. If the diffs are indistinguishable, the rule is decoration and you should delete it. This sounds tedious. It takes ten minutes and it is the only way we have found to keep rules files from rotting.

The other check is negative. When the agent does something you did not want, ask whether a rule already covered it. If a rule covered it and it happened anyway, the rule is either too vague or buried, and adding a second rule saying the same thing louder will not help.

Rules also cannot enforce anything. They are advice the model usually follows. If a constraint truly must hold, put it in a pre-commit check or CI, not in a rules file.

What to do next

Open your rules today and delete every line that is not a command, a boundary, a decision with a reason, or a precedent to copy. In the sessions we run, teams usually cut more than half on the first pass, and the agent gets noticeably more obedient the same afternoon.

If you want help putting this into practice, talk to us.

Related training topics

Related research

Ready to start?

Transform how your team builds software.

Book a 15-minute sync