Cursor Rules vs CLAUDE.md Explained
Cursor rules vs CLAUDE.md explained: how .cursor/rules/*.mdc files attach per chat with four rule types, how CLAUDE.md loads once and walks up the directory tree, and a migration map for teams running both tools.
Want the framework behind these builds?
Get the Claude Code system we use to plan, build, test, and ship production software.
Cursor rules and CLAUDE.md solve the same problem (the model forgets your project between conversations) with two different loading models. Cursor keeps a folder of small .mdc files and decides per chat which ones to attach, using four rule types. Claude Code loads CLAUDE.md files once at session start by walking up the directory tree from where you launched it, then pulls in more files as it touches subdirectories.
If you use both tools, the answer is not "pick one". It is: put shared conventions in one file both tools read (AGENTS.md), and keep each tool's scoping logic in its native format.
The Short Version
| Cursor rules | CLAUDE.md | |
|---|---|---|
| Location | .cursor/rules/*.mdc | CLAUDE.md, .claude/CLAUDE.md, CLAUDE.local.md, .claude/rules/*.md |
| Format | Markdown plus required frontmatter | Plain markdown (frontmatter only in .claude/rules/) |
| When it loads | Evaluated per chat, by rule type | At session start, plus on demand in subdirectories |
| Scoping | alwaysApply, globs, description, @-mention | Directory tree, paths in rules, skills |
| Conflict handling | Team, then Project, then User rules; earlier wins | Everything is concatenated; nothing overrides |
| Cross-tool bridge | Reads AGENTS.md (root and subdirectories) | Reads AGENTS.md when no CLAUDE.md exists, or via @AGENTS.md |
Everything below is the mechanism behind each row.
How Cursor Rules Actually Work
Cursor's docs put it plainly: models do not retain memory between completions, so rules give "persistent, reusable context at the prompt level." When a rule applies, its contents are placed at the start of the model context.
Project rules live in .cursor/rules/ and must use the .mdc extension. A plain .md file in that folder is ignored by the rules system, because it has no frontmatter to say how it should be applied. Cursor's own suggestion for people who want plain markdown is to use AGENTS.md instead.
The four rule types
Every .mdc file has three frontmatter fields: description, globs, and alwaysApply. The combination decides the rule type:
| Rule type | Frontmatter | When it is included |
|---|---|---|
| Always Apply | alwaysApply: true | Every chat. Globs and description are ignored. |
| Apply to Specific Files | alwaysApply: false + globs | When a file matching the pattern is in context |
| Apply Intelligently | alwaysApply: false + description, no globs | When the agent reads the description and decides it is relevant |
| Apply Manually | none of the above | Only when you @-mention the rule in chat |
A typical glob rule looks like this:
---
description: API route conventions
globs: src/app/api/**/*.ts
alwaysApply: false
---
- Validate every request body with Zod before touching the database.
- Return typed errors, never raw exception messages.
- See src/app/api/users/route.ts for the canonical pattern.The key property: Cursor re-decides which rules apply for each conversation. A glob rule for your API folder costs nothing while you are editing CSS. An Always rule costs its full size in every chat.
The other layers
Project rules are one of several sources Cursor merges:
- User Rules: global preferences set in Customize, applied across all projects.
- Team Rules: set by admins on Team and Enterprise plans from the Cursor dashboard. They can be enforced so members cannot switch them off, and they support glob patterns.
- AGENTS.md: plain markdown with no metadata, supported in the project root and in subdirectories.
.cursorrules: the original single file at the repo root. Older Cursor docs labeled it legacy, and the current rules docs no longer cover it at all. Migrate it to project rules or AGENTS.md.
When guidance conflicts, Cursor applies Team Rules, then Project Rules, then User Rules, and earlier sources take precedence.
How CLAUDE.md Actually Works
Claude Code has no per-chat rule selection. A session starts, and Claude Code assembles a memory stack from files on disk.
The tree walk
Launch Claude Code in foo/bar/ and it loads foo/bar/CLAUDE.md, foo/CLAUDE.md, and any CLAUDE.local.md files alongside them, all the way up the tree. On top of that come your user file at ~/.claude/CLAUDE.md and, if your organization deploys one, a managed policy CLAUDE.md.
Two details matter more than people expect:
- Files are concatenated, not overridden. Content is ordered from the filesystem root down to your working directory, so the file closest to where you launched is read last. Within a directory,
CLAUDE.local.mdcomes afterCLAUDE.md. Nothing wins by rule. If two files contradict each other, Anthropic's docs say Claude may pick one arbitrarily. - Subdirectories load lazily. A
CLAUDE.mdinsidepackages/api/is not loaded at launch. It enters context when Claude reads a file in that directory.
Rules, imports, and skills
Three mechanisms narrow what loads:
.claude/rules/*.md: rule files without frontmatter load at launch with the same priority as.claude/CLAUDE.md. Rules with apathsfield load only when Claude reads a matching file. (Deep dive in the rules directory guide.)@pathimports: a line like@docs/testing.mdexpands that file into context at launch. Imports can nest up to four hops. They help organization, but they do not save context, since imported files still load at startup.- Skills: only the name and description sit in context. The full
SKILL.mdloads when Claude decides it is relevant or when you type/skill-name.
What happens after /compact
Project-root CLAUDE.md is re-read from disk and re-injected after /compact. Nested CLAUDE.md files and path-scoped rules come back as Claude reads files they apply to. Anything you only said in chat is gone. That is the practical reason to write durable instructions into a file instead of repeating them in conversation.
The docs are also explicit about what CLAUDE.md is not: it is delivered as a user message after the system prompt, it is context rather than enforced configuration, and the target is under 200 lines per file. For anything that must happen every time, use a hook. More on sizing and structure in CLAUDE.md mastery.
The Real Difference: Who Decides, and When
Strip away the file formats and the two systems differ on one axis.
Cursor decides per chat, from metadata. Each rule carries its own trigger. The frontmatter is the contract, and Cursor's rule engine enforces it before the model sees anything.
Claude Code decides by location and access. Where the file sits (which directory, user vs project vs local) decides whether it loads at launch. What Claude touches during the session decides what loads later. The only frontmatter Claude Code reads on a rule file is paths.
That produces a few practical consequences:
- Cursor's "Always" rules and Claude's root CLAUDE.md are the expensive tier. Both ship in full every time. Keep them short in both tools.
- Cursor glob rules and Claude path rules are close cousins, with a different trigger. Cursor attaches on a matching file being in context. Claude Code attaches when Claude reads a matching file, not on every tool use.
- Cursor's "Apply Intelligently" has no rule-file equivalent in Claude Code. The equivalent is a skill: description always visible, body loaded on demand.
- Monorepos favor Claude's tree walk. A
CLAUDE.mdper package gives package-level context with zero frontmatter. In Cursor you get the same effect with globs likepackages/api/**, or with nested AGENTS.md files.
Where AGENTS.md Fits
AGENTS.md is the one format both tools understand, which makes it the natural home for rules that are not tool-specific: build commands, test commands, naming conventions, "never commit secrets", where the canonical examples live.
On the Cursor side, AGENTS.md is a first-class alternative to .cursor/rules, read from the project root and subdirectories.
On the Claude Code side, the behavior changed recently. From v2.1.277, Claude Code reads AGENTS.md directly, but by default only when there is no CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md in your working directory or above it. Your ~/.claude/CLAUDE.md and .claude/rules/ files do not count for that check, so they keep loading alongside AGENTS.md. You can change the default with the Project instructions setting in /config:
| Setting value | What Claude Code reads |
|---|---|
claude-md-or-agents-md (default) | CLAUDE.md, or AGENTS.md when no CLAUDE.md exists |
claude-md-and-agents-md | Both, CLAUDE.md first in each directory |
claude-md | CLAUDE.md only |
managed-only | Only the organization's managed file (plus auto memory) at launch |
If your repo has both files and you stay on the default, Claude Code reads CLAUDE.md only. The reliable bridge that works on every version is an import at the top of CLAUDE.md:
@AGENTS.md
## Claude Code only
- Run the test suite with the Bash tool before declaring a task done.
- Use plan mode for any change that touches more than 3 files.Claude reads the imported AGENTS.md first, then the Claude-specific lines below it. Keeping the import never makes Claude read AGENTS.md twice, whichever setting you pick. (The fuller comparison is in AGENTS.md vs CLAUDE.md.)
A symlink (ln -s AGENTS.md CLAUDE.md) also works when you have no Claude-specific content, with two caveats from Anthropic's docs: Claude's Edit and Write tools refuse to write through a symlink, and Windows clones without core.symlinks check it out as a one-line text file. On mixed-OS teams, use the import.
When to Keep Both
Keep .cursor/rules and CLAUDE.md side by side when both tools are in daily use on the same repo. The layout that avoids drift:
repo/
├── AGENTS.md # shared: commands, conventions, boundaries
├── CLAUDE.md # @AGENTS.md + Claude-only behavior
├── .claude/
│ ├── rules/
│ │ └── api.md # paths: src/app/api/**/*.ts
│ └── skills/
│ └── db-migrations/SKILL.md
└── .cursor/
└── rules/
├── api.mdc # globs: src/app/api/**/*.ts
└── ui.mdc # globs: src/components/**/*.tsxThe rule of thumb: a sentence lives in exactly one file. If it applies to both tools and to the whole repo, it goes in AGENTS.md. If it only makes sense scoped to a folder, it goes in each tool's scoped format (an .mdc with globs, a .claude/rules/ file with paths), and those two files point at the same canonical example in the codebase instead of restating it.
There is one more overlap worth knowing. Cursor also loads Agent Skills, and for compatibility it discovers skills from .claude/skills/ and ~/.claude/skills/, alongside its own .cursor/skills/ and .agents/skills/. A skill you write for Claude Code can therefore serve Cursor too, which makes skills a good home for longer procedures you want in both tools.
Drop one side when nobody uses it. A stale .cursor/rules folder that nobody edits is worse than none, because the next Cursor user inherits rules that describe last year's codebase.
Migration Map: Cursor Rules to Claude Code
Moving from Cursor to Claude Code (or running both) is mostly a translation of rule types. Here is the map:
| Cursor source | Claude Code destination | Notes |
|---|---|---|
alwaysApply: true rule | Root CLAUDE.md, or .claude/rules/name.md with no frontmatter | Both load every session. Keep it short. |
Glob rule (globs:) | .claude/rules/name.md with paths: | Rename the field. paths accepts a YAML list or a comma-separated string. |
Apply Intelligently (description:) | Skill in .claude/skills/name/SKILL.md | Move the description into skill frontmatter; Claude loads the body when relevant. |
Apply Manually (@my-rule) | Skill with disable-model-invocation: true | You invoke it with /name; Claude never pulls it in on its own. |
| User Rules | ~/.claude/CLAUDE.md or ~/.claude/rules/ | Applies to every project on your machine. |
| Team Rules | Managed policy CLAUDE.md | Deployed by IT; cannot be excluded by individual settings. |
.cursorrules | Run /init | /init reads .cursor/rules/ and .cursorrules and folds the relevant parts into the generated CLAUDE.md. |
AGENTS.md | Keep it | Import it with @AGENTS.md, or let Claude Code read it directly when there is no CLAUDE.md. |
A migrated glob rule, side by side:
<!-- .cursor/rules/api.mdc -->
---
description: API route conventions
globs: src/app/api/**/*.ts
alwaysApply: false
---<!-- .claude/rules/api.md -->
---
paths:
- "src/app/api/**/*.ts"
---The body text underneath stays the same.
A migrated manual rule becomes a skill:
---
name: release-notes
description: Draft release notes from merged PRs since the last tag
disable-model-invocation: true
---
1. Run git log from the last tag to HEAD.
2. Group changes by feature, fix, and chore.
3. Write the notes to CHANGELOG.md under a new heading.Failure Modes
These are the mistakes that show up when teams run both systems, or move from one to the other.
Copying .mdc files straight into .claude/rules/. Claude Code only reads the paths field in rule frontmatter. Every other field is ignored without an error. A copied rule with globs: src/app/api/** has no paths, so Claude Code treats it as unconditional and loads it in every session. Your carefully scoped rules all become Always rules. Rename globs to paths and check with /context.
Writing plain .md files into .cursor/rules/. The mirror image: Cursor ignores them because they have no frontmatter. The folder looks full, and none of it applies.
Adding a CLAUDE.md and losing AGENTS.md. On the default setting, the moment any CLAUDE.md exists in your working directory or above it, Claude Code stops reading AGENTS.md. Teams add a two-line CLAUDE.md for one Claude-specific tweak and silently drop the whole shared file. Fix it with @AGENTS.md at the top of that CLAUDE.md.
Assuming Claude Code has override semantics. Cursor has a precedence order. Claude Code concatenates. A "more specific" CLAUDE.md in a subdirectory does not cancel the root file; both are in context, and a conflict is resolved arbitrarily. Remove contradictions instead of layering new rules on top.
Assuming imports save tokens. Splitting a big CLAUDE.md into @ imports looks tidier, but every imported file still loads at launch. If the goal is less context, use paths rules or skills.
Relying on .cursorrules. It is the legacy format, and Cursor's current rules docs only describe .cursor/rules and AGENTS.md. If a repo still only has .cursorrules, run /init in Claude Code to pull it into CLAUDE.md, then move Cursor itself to .cursor/rules or AGENTS.md.
Duplicated rules drifting apart. The same "use Zod for validation" line in an .mdc file, CLAUDE.md, and AGENTS.md will be edited in one place and not the others within a month. Then the two agents follow different versions of the truth. One sentence, one file.
Treating either file as enforcement. Both are context, not a linter. Cursor rules shape the prompt; CLAUDE.md is delivered as a user message after the system prompt. If a rule must never be broken (no writes to .env, always run the formatter), enforce it with tooling: permissions and hooks in Claude Code, and lint or CI checks that run no matter which agent wrote the code.
Checking What Actually Loaded
Guessing is the root of most of the failure modes above, so check.
- Claude Code: run
/contextand look at the list under Memory files. It shows every CLAUDE.md and rule file in the current session./memorylists memory file locations and, on v2.1.280 and later, an AGENTS.md that Claude read directly. If a frontmatter block does not parse,claude --debugshows the error. - Cursor: open Customize and go to Rules to see every rule and its status.
Do this once after any migration. It takes a minute and catches the silent cases (ignored fields, ignored files, a CLAUDE.md shadowing AGENTS.md) that never throw an error.
Picking a Setup
- Cursor only:
.cursor/rules/*.mdcfor scoped rules, AGENTS.md for everything plain. Migrate any.cursorrules. - Claude Code only: CLAUDE.md for every-session rules,
.claude/rules/withpathsfor folder-specific rules, skills for procedures. Delete stale.mdcfiles or run/initonce to absorb them. - Both tools: AGENTS.md as the shared source,
@AGENTS.mdat the top of CLAUDE.md, scoped rules in each tool's native format, skills in.claude/skills/so both tools can discover them.
The file names differ, the loading models differ, and the frontmatter is not portable. The content mostly is. Write it once, put it where both tools can see it, and let each tool handle its own scoping.
Posted by @speedy_devv
Want the framework behind these builds?
Get the Claude Code system we use to plan, build, test, and ship production software.

