How to Write Cursor Rules That Actually Work (2026)
Published September 4, 2026
Most .cursorrules files we see are wishlists. “Write clean code.” “Follow best practices.” “Use TypeScript strict mode.” Cursor reads them and does whatever it wants anyway.
Then people conclude “rules files don’t work.” They do. Just not the way most people write them.
Here’s what NJPTEAM has found actually shifts model behavior after shipping thousands of AI-assisted commits.
Positive rules get ignored. Negative rules stick.
The single biggest change: stop writing “Do X.” Start writing “Never do Y.”
Weak rules Cursor ignores:
- “Write clean, readable code.”
- “Follow best practices.”
- “Use appropriate design patterns.”
Strong rules Cursor follows:
- “Never invent package names or CLI flags. Verify against
package.jsonbefore proposing an install.” - “Never rewrite entire files (400+ lines) for localized changes (2-20 lines). Prefer targeted edits.”
- “Never generate tests that trivially pass (
assert(true), no assertions). Every test must exercise real behavior.” - “Never silence errors (
// eslint-disable,# type: ignore,.skip()) to make the build pass unless it’s a genuine false positive with a comment explaining why.”
Why negative rules work: they map to specific failure modes. The model can pattern-match “am I about to do the forbidden thing?” as it generates code. Positive rules (“write clean code”) have no anchor.
The verification protocol is non-negotiable
Add this section to every .cursorrules file:
## Verification protocol
- After ANY code change, run `./verify.sh` from the project root.
- If exit != 0, fix the FIRST error only, then re-run.
- Do NOT declare the task complete until exit code is 0.
Details in our dedicated verify.sh post. The short version: without a feedback loop, the AI declares broken code “done.” With one, it iterates until the code actually works.
PROJECT_STATE.md for session continuity
Long AI coding sessions run out of context window. When the model forgets what it did 30 min ago, it starts contradicting itself.
Add this rule:
- Maintain a PROJECT_STATE.md at the project root. After every meaningful milestone or refactor step, checkpoint: (1) what changed, (2) what is now working, (3) what is next.
- On session start, read PROJECT_STATE.md first to resume with zero amnesia after context compression or session reset.
This is not novel — Anthropic’s own Claude Code docs recommend a similar pattern for CLAUDE.md. Cursor benefits from it too.
Token-efficient editing
Full-file reads on 5,000-line codebases eat the context window in 3-4 requests. Then the model forgets.
Add this rule:
- Use targeted search (grep, ripgrep) and inspect small line slices (10-30 lines) around the target. Do not read entire large files (500+ lines) unless the task genuinely needs full context.
Measurable difference: sessions stay coherent for 60-90 min instead of degrading at 20-30 min.
Stack-specific rules matter
Generic “use best practices” is useless. Stack-specific rules make Cursor act like a senior at that stack.
Bad: “Use modern TypeScript.” Good (Next.js):
- Server Components by default. Only "use client" if the component needs interactivity, state, or browser APIs.
- Never `useState` for server data — use `async` Server Components.
- Never `getServerSideProps` / `getStaticProps` — this is App Router, use route handlers or Server Components.
Good (FastAPI + Pydantic v2):
- Pydantic v2 ONLY. Never `parse_obj`, `.dict()`, or `class Config:` — those are v1.
- Use `Annotated[X, Depends(y)]` for dependencies, never `Depends` as default argument.
- Never mix sync and async DB calls in one endpoint.
The structure that works
Every effective .cursorrules file we’ve seen has these sections, in this order:
## Stack
[what the project is]
## Style
[positive rules about coding patterns]
## Do NOT
[negative rules — 5-8 items, specific failure modes]
## Constraints
[hard rules about what the AI cannot do without asking]
## Verification protocol
[closed-loop feedback rules — run verify.sh, iterate]
## Testing
[how tests are structured in this project]
## General
[be direct, ask one question, don't guess, etc.]
Common mistakes
- Too long. Rules files over 200 lines get ignored past the first ~150. Cut every line that doesn’t map to a specific failure.
- Vague. “Use good naming” means nothing. “Never variables named
data,info,manager” — that means something. - No enforcement. Rules without verification are suggestions.
verify.sh+ “do not declare complete until 0” is enforcement. - Ignoring the stack. Generic rules across stacks means the model has to guess which apply. Stack-specific files work.
- Never updating. Ship a rules file, notice the model still does something annoying, add a new “Do NOT” for it, ship again. Rules files are living documents.
Tools we ship
Free:
- .cursorrules Generator — interactive builder with all the sections above, negative-constraint chips, verification protocol chips, stack-specific presets
- CLAUDE.md Generator — same, for Claude Code users
- Anti-Hallucination Benchmark — measure how much your rules file reduces silent AI hallucinations
Paid (€15):
- Stack Pack — 30 pre-written
.cursorrulesfiles (one per stack), 30 matchingCLAUDE.md, and 3 full Kits (Next.js / FastAPI / Rust) with slash commands +verify.sh+ prompt recipes + anti-hallucination test suites
FAQ
How long should my .cursorrules file be?
80-150 lines. Longer than that and the model starts ignoring the tail.
Should I have one rules file or many?
One per project. Rules should be stack-specific to that project — a shared generic file wastes context on things that don’t apply.
Do the rules apply to Cursor’s Composer / Agent mode?
Yes. Both Cursor Chat and Composer read .cursorrules at the project root. Agent mode reads them too.
What’s the difference between .cursorrules and .cursor/rules/?
Cursor 2.0+ supports a folder-based .cursor/rules/ with multiple files per project. Same pattern applies — negative rules stick, positive ones don’t. Split by concern (backend rules, frontend rules, testing rules) if you use folder mode.
Are rules files the same as CLAUDE.md?
Same concept, different files. .cursorrules for Cursor. CLAUDE.md for Claude Code (Anthropic’s official CLI). Same rules structure works in both.