Project Context: The instructions file your whole team commits
Project Context β a versioned instructions file (AGENTS.md)
Every AI coding tool has some version of the same feature: a file where you write down your project's conventions once, so you don't have to repeat them in every prompt. Claude Code reads CLAUDE.md. Cursor calls them "rules." Copilot reads .github/copilot-instructions.md. Underneath, it's one idea:
π Persistent, versioned instructions that give the AI durable context about your project β its stack, conventions, boundaries, and how to build/test/run it.
Learn the idea, and every tool's flavor of it becomes trivial.
Why we need it π€
Without it, you re-explain your project in every prompt: "we use Zustand, not Reduxβ¦ arrow functionsβ¦ Tailwind, no CSS modulesβ¦" Tedious, and the AI forgets the moment the chat resets. A versioned instructions file lets you teach the AI once, commit it, and get consistent behavior for everyone who clones the repo. Teams report it measurably reduces agent-generated bugs.
The durable spine: AGENTS.md (the open standard)
The single most important development in this space is AGENTS.md β an open, cross-tool standard for exactly this. A plain Markdown file at your repo root that tells any agent how to work in the project.
- Stewarded by the Linux Foundation's Agentic AI Foundation.
- Adopted by tens of thousands of repositories.
- Read natively by Codex, Cursor, GitHub Copilot, Gemini CLI, Aider, Windsurf, Zed, and more.
Because it's a standard, you write your conventions once and every compliant tool picks them up β no lock-in to one editor's proprietary format.
β
The durable rule: write your project conventions once, in the open standard (AGENTS.md). Add tool-specific rule files only when you hit a real scoping limit the base file can't express.What belongs in AGENTS.md
Keep it to what an agent genuinely needs to be effective:
- How to build / test / run β the exact commands (
pnpm test,make lint,docker compose up). - Conventions β language, frameworks, patterns to prefer/avoid.
- Boundaries β "never touch
/legacy," "don't add new deps without asking," "all DB access goes through the repository layer." - Project shape β key directories and what lives where.
A minimal example:
# AGENTS.md
## Commands
- Install: `pnpm install`
- Test: `pnpm test`
- Lint: `pnpm lint`
- Dev: `pnpm dev`
## Conventions
- TypeScript strict mode. Prefer arrow functions; destructure props at the signature.
- State: Zustand. Styling: Tailwind (no inline styles, no CSS modules).
- Never introduce a new dependency without flagging it first.
## Boundaries
- `/src/legacy` is frozen β read for context, do not modify.
- All network calls go through `src/lib/api.ts`.
Tool-specific files are overlays on top of the base
When a base file isn't enough β you need path-scoped rules, or a tool-only feature β reach for the tool's own format. Treat these as overlays, not the foundation:
| Concept | Portable base | Claude Code | Cursor | GitHub Copilot | Windsurf |
|---|---|---|---|---|---|
| Project instructions file | AGENTS.md |
CLAUDE.md |
.cursor/rules/*.mdc |
.github/copilot-instructions.md |
.windsurfrules |
β οΈ Precedence & layering. When several files exist, a root file sets defaults and nested/scoped files refine them; a tool overlay adds tool-specific behavior on top of the portable base. Keep the layers few and intentional β overlapping rule files that contradict each other confuse both humans and agents.
Example: scoping rules as a general pattern
Good instruction systems let you control what applies where. Claude Code (today) does this with a memory hierarchy β a nice illustration of a general pattern other tools implement differently:
| Pattern | Claude Code | When it applies |
|---|---|---|
| Always-on, shared | project CLAUDE.md (repo root, committed) |
Every request in this repo, for the whole team |
| Path-scoped | nested CLAUDE.md in a subdirectory |
When you're working in that subtree |
| Personal, global | ~/.claude/CLAUDE.md (your machine) |
All your projects, not shared |
| Personal, this repo | CLAUDE.local.md (gitignored) |
This repo, just you |
| Composed | @path/to/file imports |
Pulls another file's content into context |
You don't need Claude Code for this idea β you need to know that good instruction systems let you scope rules always / by path / personally / composed from pieces. Cursor expresses the same idea differently (its .mdc rules take an alwaysApply flag and globs for path-scoping, an agent-requested description, or manual @rule invocation).
ποΈ Legacy note (Cursor): Cursor's old single-file.cursorrulesat the repo root is deprecated and ignored by Agent mode. Don't teach or copy it β useAGENTS.mdfor the portable base and.cursor/rules/*.mdcfor Cursor-specific overlays.
Working example β a CLAUDE.md
Claude Code's file is plain Markdown β no frontmatter, no globs. You just write the instructions:
# CLAUDE.md
You are working in a Next.js 15+ / TypeScript / TailwindCSS project.
When creating components:
1. **Always use a state management library** β prefer Zustand unless told otherwise.
2. **Apply modern styling** β use TailwindCSS classes; no inline styles or CSS modules.
3. **Follow best practices** β arrow functions for components; destructure props at the signature.
## Commands
- Test: `pnpm test` Β· Lint: `pnpm lint` Β· Dev: `pnpm dev`
π Cursor overlay equivalent (a `.mdc` rule) β and a caution
Cursor's rule files add YAML frontmatter. A correct one:
---
description: Conventions for a Next.js 15+ project with modern React/Tailwind best practices
globs: "**/*.{ts,tsx,js,jsx}"
alwaysApply: true
---
1. **Always use a state management library** β prefer Zustand unless told otherwise.
2. **Apply modern styling** β use TailwindCSS classes; no inline styles or CSS modules.
Note the valid, quoted globs and proper **bold**. An earlier version of this course shipped globs: '***/*.ts, */.tsx' with broken bold β anyone who copied it got a rule that misbehaved. Errors in a teaching example get absorbed as "the right way" β always verify your example applies as claimed.
Rules aren't just a frontend thing
The examples above are React, but instruction files encode any stack's conventions. A backend or infra example:
# AGENTS.md (Python service)
## Commands
- Test: `pytest -q`
- Lint: `ruff check .` and `mypy src`
## Conventions
- Python 3.12, type hints required. Prefer `httpx` over `requests`.
- Use SQLAlchemy 2.0 style; no raw SQL unless justified in a comment.
- Public functions need docstrings (Google style).
## Boundaries
- Migrations only via Alembic; never edit the DB schema by hand.
Same idea for Go, Terraform, Kubernetes manifests β the file just captures this project's rules.
What makes a good instructions file (vs. a bloated one)
More is not better. Context has a real cost β every token you add is a token the model must read on every request, and a bloated file crowds out the actual task (this is why Context Engineering is its own lesson).
- β
Concise, testable conventions β "use Zustand," "all API calls go through
api.ts." - β Don't dump your entire style guide or paste whole docs β link to them instead.
- β Prefer rules the AI can act on, not vague aspirations ("write good code").
User / global rules (personal, not shared)
Most tools also support personal, global preferences that apply to all your projects and are not committed (e.g. "always add JSDoc," "explain changes in this format"). Keep these for genuinely personal taste; anything the team should share belongs in the committed AGENTS.md, not your personal settings.
How to set it up (outcome first)
The durable instruction is simple, and survives any UI change:
Create a versioned instructions file at your repo root (AGENTS.md), write your conventions, and commit it. That's it β everyone who clones the repo now shares the same AI guidance.π In Claude Code today (exact commands β will drift)
- Scaffold it: run
/initin your repo β Claude Code inspects the project and drafts a starterCLAUDE.mdfor you to edit and commit. - Add a memory fast: start a line with
#in the chat and Claude Code appends it to the right memory file. - Edit/review memories: run
/memory. - Scope it: drop a
CLAUDE.mdinside a subdirectory for path-scoped rules; use@path/to/fileto import shared snippets; keep personal notes in a gitignoredCLAUDE.local.md.
(In Cursor: Ctrl/Cmd+Shift+P β Cursor Settings β Rules & Memories β Add Rule, which creates .cursor/rules/{name}.mdc.)
Commands and menu names are current as of 2026-07 and are exactly the kind of thing that changes β rely on the outcome above, not the clicks.
Next: you've given the AI standing context. Now learn to communicate with it precisely β Prompt Engineering.
Member discussion