Skip to content
vibespell

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

  1. 01

    Add one always-on rule

    Put stack, commands, and layout in `.cursor/rules/project.mdc` with alwaysApply true.

  2. 02

    Split tests and security

    Put those in their own .mdc files with globs so they attach only when relevant.

  3. 03

    Delete contradictions

    If a root .cursorrules file disagrees, update it or remove it.

  4. 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.