Cursor rules best practices
How to structure .cursor/rules and .cursorrules so Cursor applies the right constraints without drowning every edit.
Prefer small .mdc files
Modern Cursor reads `.cursor/rules/*.mdc`. Each file has frontmatter: a description, globs, and whether it always applies. An always-on project rule should cover the stack and the commands. A testing rule should set alwaysApply to false and glob to the test files.
The older `.cursorrules` file at the repo root still works on some setups. If you keep it, do not also contradict the .mdc files. One source of truth.
Write rules the model can obey
Name files, commands, and banned APIs. 'Be careful with auth' does nothing. 'Do not put secrets in NEXT_PUBLIC_ variables' does. Keep each rule file focused so the description Cursor shows in the picker is honest.
After you add a rule, start a new chat. An open chat may still be using the previous instructions. Ask for a change that would violate the rule and see if the agent refuses.
Do it in this order
01
Add one always-on rule
Put stack, commands, and layout in `.cursor/rules/project.mdc` with alwaysApply true.
02
Split tests and security
Put those in their own .mdc files with globs so they attach only when relevant.
03
Delete contradictions
If a root .cursorrules file disagrees, update it or remove it.
04
Retest in a new chat
Confirm Cursor quotes the command you specified.
Questions
Should every rule always apply?
No. Always-on rules compete with the task. Keep one short project rule, and attach testing or security rules with globs.
Do globs use gitignore syntax?
Use the glob pattern Cursor documents for .mdc files, such as **/*.{test,spec}.ts. Narrow them when a folder is known.