Claude Code reads CLAUDE.md from your project root. Most other coding agents and editors read AGENTS.md, which emerged as the vendor-neutral convention for the same job. The practical answer is not to pick one: write the content once, then make the second filename point at it, so you never maintain two files that quietly disagree.
The short answer
Create AGENTS.md as the canonical file. Make CLAUDE.md a symlink to it. Commit both. That gives Claude Code the file it looks for, gives every AGENTS.md-aware tool the file it looks for, and gives you exactly one document to edit.
# from the project root
ln -s AGENTS.md CLAUDE.md
git add AGENTS.md CLAUDE.md
git commit -m "chore: single canonical agent instruction file"
If symlinks are a problem on your team (Windows contributors, or a build system that dereferences them badly), use a one-line stub instead:
<!-- CLAUDE.md -->
See [AGENTS.md](./AGENTS.md) for all project instructions.
Agents follow that pointer reliably in practice, because reading a referenced file in the same repo is the one thing they are unambiguously good at. What you should not do is keep two full copies and promise yourself you will update both.
If you want a starting point rather than a blank file, we keep a set of stack-specific templates at /templates/agents-md, and a generator that builds one from your repo's actual structure at /free-tools/agents-md-generator.
What each file actually is
CLAUDE.md is Anthropic's convention for Claude Code. The agent looks for it in the project root at session start and loads it into context. It also supports nested files: a CLAUDE.md inside packages/api/ applies when the agent is working in that subtree, which is genuinely useful in a monorepo where the frontend and backend have different rules. There is also a user-level file in your home Claude config for personal preferences that should not be committed to a shared repo, which is the right place for "always run tests with my alias" type instructions.
AGENTS.md is a cross-tool convention. It started as an attempt to stop every vendor inventing its own dotfile, and it got adopted broadly: many agents, CLIs, and editor integrations now look for it by default. The format is deliberately boring. It is plain Markdown with headings. There is no schema to validate against, no frontmatter requirement, no directive syntax. That is a feature. The consuming agent is a language model, and the thing language models parse most reliably is ordinary prose under clear headings.
Now the honest part. Support is uneven and it moves. "Adopted by many tools" is not the same as "guaranteed in the version your teammate installed." Some tools read AGENTS.md automatically, some read it only if you configure a rules path, and some read it but truncate aggressively when the file is long. The only reliable way to know is to check: open the tool, ask it to state a specific rule from your file, and see if it can. A rule like "our package manager is pnpm, never npm" is a good canary, because you will immediately notice when it is ignored.
Two other files show up constantly and are worth naming. Cursor historically used .cursorrules, then moved to a .cursor/rules directory with scoped rule files. Plenty of projects now skip both and point Cursor at AGENTS.md instead. If you are still on the older format and want to move, /free-tools/cursorrules-generator covers that shape specifically. Beyond that, repos accumulate .github/copilot-instructions.md and windsurf.rules, and this is where the real cost appears. Four files, four slightly different truths, and no CI check on any of them. The sprawl is the problem, not any individual file.
The symlink pattern
The symlink is the most robust of the options because there is exactly one set of bytes on disk. There is no copy to drift.
# canonical file lives at AGENTS.md
ln -s AGENTS.md CLAUDE.md
# add more aliases the same way if your team needs them
mkdir -p .github
ln -s ../AGENTS.md .github/copilot-instructions.md
# verify
ls -l CLAUDE.md
# CLAUDE.md -> AGENTS.md
Note the relative path in the second example. A symlink stored in a subdirectory must be relative to that subdirectory, not to the repo root, or it will resolve to nothing once someone clones the repo elsewhere.
Two caveats before you commit.
Git stores symlinks, but only if it is configured to. Git records a symlink as a special blob containing the target path, so it does travel through clones correctly. But core.symlinks can be false, and on Windows it defaults that way unless the user has Developer Mode enabled or runs Git with elevated permissions. When it is off, Git checks out a plain text file whose entire contents are the string AGENTS.md. An agent reading that file gets one useless word. This fails silently, which is the worst kind of failing.
Windows and some tooling dereference or break links. Docker builds that copy files, deployment steps that rsync without -l, and a few editor sync tools will all quietly turn your symlink into a copy or a broken pointer. If any of those are in your pipeline, use the stub file. A one-line stub costs you one indirection and works everywhere.
The third option, generating both files from a shared source at build time, is worth it only if you have real reason to differ between them, for example a Claude-specific section about subagents that would confuse other tools. Keep the source in docs/ or a small script, and add the generated files to the same commit. The moment your generator can be skipped, you are back to maintaining copies by hand.
What belongs in the file
Six blocks cover nearly everything useful.
1. Project overview. Three to five sentences. What the app does, the stack, where the entry points are. Enough for the agent to orient, not a rewrite of your README.
2. Runnable commands. The exact strings, copy-pasteable, with the package manager named. This is the single highest-value section, because agents guess commands otherwise and guess wrong.
## Commands
- `pnpm dev` start dev server on :5173
- `pnpm test path/to/file.test.ts` run one test file
- `pnpm check` typecheck, must pass before any commit
3. Code style rules. Specific and checkable. Compare these two:
Bad: Write clean, maintainable, idiomatic code.
Good: No default exports. Every component file exports one named
component. Data fetching lives in +page.server.js, never in
the component.
The first is unfalsifiable, so it changes nothing about the agent's output. The second is a rule the agent can apply and you can review against.
4. Explicit boundaries. What not to touch, and why. src/generated/ is written by a codegen step and edits will be overwritten. migrations/ is append-only, never edit an applied migration. Do not modify package.json scripts without asking. Boundaries prevent the expensive class of mistake, so put them early in the file where truncation cannot reach them.
5. Test instructions. How to run a single test, what the test file naming convention is, whether new code needs tests to land. If your suite takes eleven minutes, say so and say what the fast subset is, otherwise the agent will run the whole thing on every iteration.
6. Git workflow. Branch naming, commit message format, whether to commit at all without being asked, whether to push. Agents are inconsistent about this by default and a two-line rule fixes it permanently.
What does not belong
Aspirational essays. "We value simplicity and craft" is not actionable. If a value matters, express it as a rule with a subject and a verb.
Duplicated README prose. Two documents describing your architecture will diverge within a month. Link to the README, do not restate it.
Anything the agent cannot verify. "Our users prefer minimal interfaces" is unusable, because the agent has no way to check any decision against it. Convert to a rule: "no modal dialogs, use inline panels."
Full API documentation. It bloats context and it goes stale. Point at the file or the generated docs instead: "route definitions are in src/routes/api/, read the relevant one before adding an endpoint."
Secrets, keys, connection strings. Obvious, and yet. This file is committed and it gets pasted into chat windows.
Very long files in general. Past roughly 200 lines, the middle of your file competes with the actual task for attention. If you have more to say, use nested per-directory files so each one is short and locally relevant.
Keeping it from rotting
The failure mode is not a bad first draft. It is a good file that describes a project from six months ago. Commands drift when someone swaps the test runner. Boundaries go stale when src/generated/ becomes hand-maintained. Style rules linger after the lint config already enforces them, which is harmless but adds noise, or contradicts the lint config, which is not harmless.
Treat it as code:
- Review it in PRs. If a PR changes a build command, the diff should touch the instruction file too. A CODEOWNERS entry on the file makes this hard to skip.
- Test the commands. A CI step that runs every command listed under
## Commandscatches drift the day it happens. This is a ten-line script and it is the highest-leverage thing in this section. - Delete more than you add. Files grow monotonically unless someone prunes. Anything the linter, type checker, or formatter already enforces can come out.
- Date the assumptions that will expire. "As of the Node 22 upgrade" tells a future reader whether a line is still load-bearing.
A quick check that works: start a fresh agent session, give it a small real task, and read what it does before approving anything. If it runs the wrong command or edits a file you thought was off limits, your instruction file has a hole in exactly that spot.
If you are choosing a starter kit, this is worth checking before you buy. We tag the ones that ship a real instruction file, not a placeholder, at /categories/Agent-Ready, and the broader evaluation criteria are in our AI-agent-ready boilerplate checklist.
Frequently Asked Questions
Does Claude Code read AGENTS.md?
Claude Code looks for CLAUDE.md by default, so an AGENTS.md file sitting alone in your repo is not guaranteed to be loaded. This is exactly why the symlink or stub pattern exists: point CLAUDE.md at AGENTS.md and Claude Code loads your canonical content through the filename it expects. If you would rather not add a second filename, you can also reference AGENTS.md explicitly at the start of a session, but that relies on a human remembering, which is not a strategy.
Can I have both CLAUDE.md and AGENTS.md in the same repo?
Yes, and most repos should, but only one of them should contain content. Make one canonical and make the other a symlink or a one-line pointer. Two full files with overlapping content is the setup that fails, because a rule gets updated in one and not the other and you end up with agents behaving differently depending on which tool a teammate opened.
Which file takes priority if both exist with different content?
Each tool loads whichever filename it is configured to look for, so there is no global priority order to appeal to. Claude Code takes CLAUDE.md, AGENTS.md-aware tools take AGENTS.md, and neither knows the other file exists. That is precisely why the conflict is unresolvable by convention and has to be prevented at the filesystem level with a symlink or a stub.
How long should an agent instruction file be?
Aim for under 200 lines in the root file. Past that, the content in the middle starts competing with the actual task for the model's attention, and specific rules get diluted by general ones. If your project genuinely needs more, split it: keep the root file short and global, then add nested files in subdirectories so each one is short and only loads when the agent is working in that area.
Do I still need .cursorrules if I have AGENTS.md?
Probably not. Cursor moved from .cursorrules to a .cursor/rules directory, and many projects now skip both by pointing Cursor at AGENTS.md instead. Keep a Cursor-specific file only if you need rules that genuinely differ per tool, for example editor-specific behaviour that would confuse a terminal agent. Otherwise every extra file is another copy to keep in sync, and sync is the thing that always fails.