AI Tool Picks

2026-05-19 · 11 min read

How to Write Cursor Rules That Actually Work (.cursor/rules/ MDC Format, 2026)

I pay for Cursor Pro+ at $60/month out of my own pocket — nobody sponsored this review.

Most .cursorrules files I see are too generic to help. They say things like "write clean code" or "follow best practices," which sounds fine but gives Cursor almost nothing specific to follow.

A useful rules file should describe how this project works. It should tell Cursor what stack you use, where important files live, what patterns to copy, and what mistakes to avoid.

The 2026 Update: Why .cursorrules Stops Working in Agent Mode

Cursor officially deprecated the single .cursorrules file format. The new standard is a .cursor/rules/ directory with separate .mdc rule files.

The important part is not the file extension. The important part is Agent mode. Cursor's docs and independent testing show that .cursorrules is silently ignored when you use Agent mode.

That means if you use Composer or Agent at all, your old .cursorrules file is giving those sessions zero guidance. Chat may still pick it up, and Composer may still load it, but Agent mode is where the old format breaks down.

My honest advice: migrate now. If your rules matter, move them into .cursor/rules/*.mdc and delete the old file so you do not think you are protected when you are not.

What Are Cursor Rules?

Cursor rules are project instructions that guide how Cursor answers questions and edits code. In 2026, project rules should live in .cursor/rules/ as Markdown files, usually .mdc, with optional YAML frontmatter.

I think of rules as the short onboarding note I would give to a new developer. If someone joined my project for one day, what would they need to know before touching files? That is what belongs in the rules.

The useful frontmatter fields are description, globs, and alwaysApply. Those fields decide when a rule is active and whether Cursor can request it during a task.

There are four activation modes I care about:

  • Always Apply: alwaysApply: true
  • Auto Attached: matched by globs
  • Agent Requested: selected by the rule description
  • Manual: referenced directly with @rule-name

The legacy .cursorrules file still loads in Chat and Composer, but not in Agent mode. If you use Agent mode, .cursor/rules/ is the format that matters.

AGENTS.md at the project root is a simpler fallback format Cursor also reads. I still prefer .cursor/rules/*.mdc for real projects because I can split rules by topic and attach them to specific files.

Rules are not magic. They will not make Cursor understand a messy codebase perfectly. But they can reduce repeated explanations. Instead of telling Cursor every time that this is a Next.js App Router project using Tailwind and MDX, I write it once.

The best rules are concrete. "Use Server Components by default in src/app" is better than "write modern React." "Do not add new dependencies without asking" is better than "keep the app lightweight."

I usually add rules after I understand the project. If I write them too early, I tend to include guesses. If I write them after a few real edits, I know which instructions actually matter.

Why Most Cursor Rules Files Are Useless

Most rules files fail because they are copied from someone else's project. A rules file for a Python data pipeline does not help a Next.js blog. A rules file for a large team app may be too heavy for a solo side project.

The second problem is vague language. Cursor cannot reliably act on "be careful" or "use good architecture." I need to say what careful means in this repo. For example: "Before editing a shared component, search for all imports and mention likely affected pages."

The third problem is rule overload. If I paste fifty rules into the project, the important ones disappear. Cursor may follow some, ignore others, or spend too much attention on instructions that do not matter for the task.

I try to keep rules short enough that I would actually read them myself. If the file feels like a company handbook, it is probably too long. A good first version can be 20 to 40 lines.

The final problem is rules that never get updated. A project changes. The stack changes. Folder names change. If the rules still describe an old architecture, Cursor will make worse suggestions. I treat rules like code: small, specific, and updated when they become wrong.

The 5 Rules Every Project Needs

The first rule should name the stack. Cursor should know whether the project is Next.js, Django, FastAPI, Rails, or something else. It should also know the language, styling system, test setup, and package manager.

The second rule should describe the file structure. I usually mention the routes directory, components directory, data layer, test folder, and content folder if the project has one. This stops Cursor from inventing new places for code.

The third rule should describe the default implementation style. For example, "prefer small server-side helpers over client-side fetches" or "use existing component patterns before creating new abstractions." These rules affect real edits.

The fourth rule should state what not to change. This is underrated. If I do not want Cursor touching generated files, environment files, migrations, or shared design tokens without asking, I say that.

The fifth rule should define verification. I tell Cursor which commands matter. For a Next.js project, that might be npm run lint and npm run build. For a Python project, it might be pytest and ruff check.

Here is the pattern I use:

.cursor/rules/01-project-core.mdc
---
description: Core project context — always applied
alwaysApply: true
---

# Project Context

- This is a Next.js App Router project using TypeScript and Tailwind CSS.
- Routes live in src/app.
- Shared components live in src/components.
- Blog content lives in content/posts as MDX.

# Implementation Rules

- Prefer Server Components unless interactivity requires a Client Component.
- Reuse existing components and styling patterns before creating new ones.
- Do not add dependencies without explaining why.
- Do not edit generated files or environment files unless explicitly asked.

# Verification

- After meaningful code changes, run npm run lint.
- Run npm run build when routes, metadata, or MDX rendering changes.

This is not fancy. That is why it works. It tells Cursor what kind of project it is in and what behavior I expect.

Rules for Next.js Projects

Next.js projects need rules because there are many ways to build the same feature. Without guidance, Cursor might add a Client Component where a Server Component would be simpler, or create a fetch pattern that does not match the app.

My first Next.js rule is usually about App Router. I tell Cursor that routes live in src/app, metadata should use the App Router metadata API, and dynamic pages should use the existing project pattern. That prevents old Pages Router suggestions.

I also mention styling. If the project uses Tailwind, I tell Cursor to use Tailwind classes and existing layout patterns. If there is a design system, I mention where it lives and ask Cursor to reuse it.

Data loading rules matter too. I do not want random client-side fetches if the rest of the app uses Server Components. A useful rule is: "Fetch data in Server Components by default. Use Client Components only for state, browser APIs, or interactive UI."

For content sites, I add MDX rules. I tell Cursor where posts live, which frontmatter fields are required, and how slugs are generated. That makes it much easier to add new posts without breaking the blog.

A good Next.js rules file is not a Next.js tutorial. It is a description of how your specific Next.js project works.

Rules for Python Projects

Python rules look different because the common mistakes are different. I usually care about environment setup, formatting, type hints, error handling, and tests.

For a Python API, I tell Cursor which framework is used, where routes live, where service logic belongs, and how database access is handled. I do not want route handlers filled with business logic if the project already has a service layer.

For data scripts, I care about reproducibility. I tell Cursor not to hardcode local paths, not to print secrets, and to make input/output paths explicit. I also tell it to keep scripts runnable from the command line.

Formatting rules help. If the project uses ruff, black, mypy, or pytest, I name those tools. Cursor is more likely to produce code that fits the project if it knows the checks.

Here is a small Python rule set I would actually use:

.cursor/rules/02-python-api.mdc
---
description: Python API conventions for services and tests
globs: ["**/*.py"]
---

# Python Project Rules

- Use Python 3.12 syntax.
- Prefer typed functions for public helpers.
- Keep FastAPI route handlers thin; put business logic in services.
- Do not swallow exceptions silently.
- Use pytest for tests and keep fixtures in tests/conftest.py.
- Run ruff check and pytest after meaningful changes.

Again, the goal is not to list every Python opinion. The goal is to preserve the local shape of the project.

Example: My .cursor/rules/ Setup

This is the kind of .cursor/rules/ setup I would start with for a small Next.js blog or SaaS project. I would edit it after the first few real features.

.cursor/rules/01-core.mdc
---
description: Core project context and safety rules
alwaysApply: true
---

# Stack

- Next.js App Router with TypeScript.
- Tailwind CSS for styling.
- Shared React components live in src/components.
- App routes live in src/app.

# Safety Rules

- Prefer simple, readable code over clever abstractions.
- Reuse existing components, utilities, and route patterns before adding new ones.
- Do not add a dependency unless the task clearly needs it.
- Do not edit .env files.
- Do not edit generated files.
- Do not rename routes without asking.

# Verification

- Run npm run lint after code changes.
- Run npm run build after route, metadata, or MDX changes.
.cursor/rules/02-content.mdc
---
description: MDX content rules for blog posts
globs: ["content/**/*.mdx"]
---

# Content Rules

- MDX posts must include title, description, date, and tags in frontmatter.
- Dates should use YYYY-MM-DD.
- Keep writing direct, first-person, and practical.
- Do not make claims about tools I have not used without research-based wording.
.cursor/rules/03-components.mdc
---
description: React component conventions
globs: ["src/components/**"]
---

# Component Rules

- Prefer Server Components unless browser state, event handlers, or browser APIs require a Client Component.
- Reuse existing components and styling patterns before creating new ones.
- Before changing shared components, check where they are imported.
- Keep props simple and typed.

The important part is that these files are specific. They mention the stack, file locations, content rules, safety rules, and verification commands. Cursor has enough direction to behave better, and Agent mode can actually see the relevant rules.

I would not copy this setup exactly into every project. I would change it for the actual stack. If the project uses Prisma, I would mention Prisma. If it uses Supabase, I would mention Supabase. If it has a custom design system, I would name it.

Common Mistakes to Avoid

The first mistake is keeping a .cursorrules file when you use Agent mode. If you have ever clicked into Agent mode, your old .cursorrules file is not loading. The fix is to move your rules into .cursor/rules/*.mdc and delete the old file.

Another mistake is writing rules for an imaginary perfect project. Rules should describe the repo you have, not the repo you wish you had. If your project has a simple structure, do not invent a complex architecture in the rules file.

Another mistake is adding too many style opinions. Cursor does not need a full essay about clean code. It needs the few constraints that change the output. Keep the rules short enough to stay useful.

Another mistake is using rules to avoid reviewing diffs. Rules help Cursor start closer to the right answer, but they do not remove your responsibility. I still check every diff, especially when shared components, auth, billing, or database code changes.

Another mistake is forgetting negative instructions. If there are files Cursor should not touch, say so. If there are patterns you do not want, say so. "Do not create a second API client" can save a lot of cleanup.

The last mistake is never revisiting the file. I update rules when I notice repeated friction. If I keep telling Cursor the same thing in prompts, that instruction probably belongs in the rules.

My final advice is to start small. Write a rules file with the stack, structure, coding style, safety notes, and verification commands. Use it for a week. Then update it based on what Cursor still gets wrong.

If you're new to Cursor, also check out 10 Cursor AI Tips I Wish I Knew as a Beginner.

For more on which Cursor features I actually use day to day, see Cursor Keyboard Shortcuts: The 5 I Actually Use Every Day and Is Cursor AI Worth $20/Month.