An AI agent without an instruction file is a senior engineer on day one with no onboarding doc. Expensive, slow, and dangerous. They read the code, guess the conventions, ship something that compiles, and miss the unwritten rules that everyone else has internalized. Three sessions in, they have made the same mistake four different times, each time costing tokens and trust. The cost of writing the file is small. The cost of not writing it is paid every session, in tokens, in time, in subtle bugs that ship.
This page covers the convention that solves that: dropping a plain-text instructions file at the root of your repository so any agent operating on the codebase reads it before doing anything else. The two filenames that matter in 2026 are AGENTS.md and CLAUDE.md. They look like documentation. They are actually a contract.
The Convention That Emerged (And Why)
The story is short and the trajectory is steep. Three years, three phases, one stable convention.
In 2023, AI coding assistants existed but no one wrote dedicated instruction files for them. People shoved hints into the project README, wrote a section called "For AI assistants" that the assistants did not actually read, or pasted boilerplate into every chat session. The pattern was ad hoc. Each project handled it differently. Most did not handle it at all.
In 2024, individual tools started shipping their own conventions. Cursor introduced .cursorrules, a plain-text file in the repo root that the editor would inject into every prompt. GitHub Copilot rolled out .github/copilot-instructions.md. Aider documented .aider/conventions.md. Each tool solved its own problem. Each tool created its own format. A repo using three different agents accumulated three different files, all saying roughly the same thing.
Anthropic's Claude Code launched with CLAUDE.md, a file the agent reads automatically from the working directory and from every parent directory up to the home folder. The hierarchy was a real innovation: a global file with universal preferences, a project-level file with project specifics, a subdirectory file for monorepo packages. The agent merges them in priority order.
The cross-tool standard that finally won is AGENTS.md. OpenAI's Codex CLI adopted it. Google's Jules and Gemini's coding agent honor it. Sourcegraph Amp picked it up. Cursor added support alongside .cursorrules. By early 2026, AGENTS.md is the file every serious agentic tool will read if it exists, and CLAUDE.md is the Claude-specific extension that often supersedes or complements it. Most professional repos with AI workflows now ship at least one of these files at the root.
The pattern that makes the convention work is boring and load-bearing. The file lives at the repo root with a fixed filename. Agents discover it without configuration. Humans can read it without a translator. Version control tracks it like any other file. There is no plugin to install, no service to register with, no API key to configure. It is the simplest thing that could possibly work, which is why it works.
That simplicity also reveals what the file is for. It is not documentation in the conventional sense. It is not architecture decision records. It is not a project wiki. It is the thing you would tell a competent engineer who joined your team this morning, before they touched a single line of code. The first hour of context. Compressed, declarative, and current.
A useful frame: think of AGENTS.md as a system prompt that ships with the codebase. Every agent that operates on the repo gets this prompt prepended to its session. The cost of writing the file is paid once. The benefit is paid out per session, indefinitely. If your team runs five agent sessions a day across a project, that is roughly 1,800 sessions a year. A file that saves even thirty seconds per session of reorientation pays for itself in the first month, and the savings keep compounding.
The economic argument is also a tokens argument. Without an instruction file, each session begins by sampling the codebase: the agent runs ls, opens package.json, reads the README, greps for conventions. That work consumes input tokens, output tokens, and wall-clock time. Most of it is rediscovering the same facts that were rediscovered yesterday. With an instruction file, the same context loads in roughly 200 lines of plain text and the agent moves directly to the work that actually matters. The cost differential per session is small. Aggregated across a team and a year, it is the difference between a useful tool and an expensive one.
What Goes in AGENTS.md
The purpose of AGENTS.md is to orient any AI agent operating on the codebase before it starts making changes. That framing is the discipline. Anything that does not help with orientation does not belong. Anything that orients fast belongs.
Seven sections show up in almost every well-written file. Together they map to the questions any new collaborator asks, in the order they ask them.
What this is. One or two sentences explaining the project at the highest possible level. Not the marketing pitch. The technical summary. "A Next.js storefront for selling print books, deployed on Vercel, backed by Stripe and a Postgres database." That sentence eliminates ten guesses an agent would otherwise make.
Project structure. Where the important files live. Not a full tree. The five or ten directories that matter most, with a one-line description of each. src/server/ for API routes. src/components/ for shared React components. scripts/ for one-off CLI tools. The agent does not need a map of every leaf. It needs to know which floor the bathroom is on.
Tech stack. Languages, frameworks, key libraries, and notable versions. "TypeScript 5.4 strict mode, Next.js 15 App Router, Tailwind CSS 4, Drizzle ORM with Postgres 16." The agent does not have to grep package.json and reconstruct the picture. The picture is in the file.
Build and deploy. How to actually run things. The exact commands. pnpm dev for local. pnpm build for production. pnpm test for tests. pnpm lint for the linter. If there is a non-obvious step, like running database migrations before the dev server, document it. If there is a deploy hook, name the platform and the trigger.
Constraints and conventions. What NOT to touch, naming patterns, style rules. This is the section that earns the file its keep. "Do not modify src/generated/; it is regenerated from the schema." "All API routes are typed with Zod schemas; do not introduce ad-hoc validation." "Use cn() from @/lib/utils, not inline class string concatenation." Specific. Operative. Useful.
Documentation. Links to deeper docs. The architecture decision records folder. The API reference. The internal wiki page if one exists. The llms.txt file if the project ships one. The agent does not have to follow every link, but it should know where to look when the question is too deep for the instruction file alone.
Related projects. Sister repos, dependencies, where to find related context. If the storefront talks to a separate inventory service, name the service and link the repo. If the project consumes a private SDK, mention the SDK. The agent now knows what is in scope and what is out of scope.
Below is a real-shape AGENTS.md skeleton for a typical web application. Read it as a template, not a prescription.
# AGENTS.md
## What this is
A Next.js 15 storefront for selling print books. Deployed to Vercel.
Stripe handles checkout. Postgres on Neon stores orders, users, and inventory.
Single repo, no monorepo.
## Project structure
- `src/app/` -- Next.js App Router routes
- `src/components/` -- shared React components
- `src/server/` -- server-side helpers and API logic
- `src/db/` -- Drizzle schema, migrations, queries
- `src/lib/` -- utilities (Stripe client, auth, formatters)
- `scripts/` -- one-off CLI tools (data backfills, fixture seeders)
- `tests/` -- Playwright e2e + Vitest unit tests
## Tech stack
- TypeScript 5.4 (strict mode)
- Next.js 15 (App Router, RSC)
- React 19
- Tailwind CSS 4
- Drizzle ORM 0.36 + Postgres 16 (Neon)
- Stripe Node SDK 17
- Playwright 1.49 + Vitest 2.1
- pnpm 9 (lockfile is canonical)
## Build and deploy
- `pnpm dev` -- local dev server (http://localhost:3000)
- `pnpm build` -- production build
- `pnpm test` -- Vitest unit tests
- `pnpm test:e2e` -- Playwright e2e
- `pnpm lint` -- ESLint + TypeScript check
- `pnpm db:migrate` -- apply pending Drizzle migrations
- Deploy: push to `main` triggers Vercel production build
## Constraints and conventions
- Do not edit `src/db/migrations/`; generate via `pnpm db:generate`
- Do not edit files under `src/generated/`
- All API routes use Zod schemas in `src/server/schemas/`
- Use `cn()` from `@/lib/utils` for conditional classes
- Server components by default; client components opt in with `"use client"`
- Database access only through `src/db/queries/`; never raw SQL in route handlers
- Stripe webhook handler is in `src/app/api/webhooks/stripe/route.ts`; signature verification is mandatory
## Documentation
- ADRs: `docs/adr/`
- API reference: `docs/api.md`
- Internal wiki: https://wiki.example.com/storefront
- llms.txt: `/llms.txt` (served at production root)
## Related projects
- `inventory-service` repo: separate Go service for stock levels
- `admin-dashboard` repo: internal Next.js admin panel, shares auth
- Stripe webhook receiver: see `inventory-service/cmd/webhook/`
Read that file. It is short. Less than 60 lines of meaningful content. An agent that reads it knows what to build, what not to break, and where to look when in doubt. A junior engineer who reads it will be productive faster than one who has to ask Slack.
One detail worth lingering on: every section above is operative, not descriptive. The "Project structure" section does not say "this is a typical Next.js layout." It names the actual directories. The "Tech stack" section does not say "we use modern tooling." It lists exact versions. The "Constraints" section does not say "follow the team's conventions." It enumerates them. This is the editorial discipline that separates a useful instruction file from a useless one. Every line earns its place by reducing some specific guess the agent would otherwise make.
A second detail: the file is written in the imperative or declarative mood, not the conversational one. Compare "Do not edit files under src/generated/" with "We typically don't recommend editing files under src/generated/ because they're regenerated from the schema and your changes will be overwritten." Both statements convey the same information. The first is one line of unambiguous guidance the agent will follow. The second is three lines of context the agent has to parse for the actual rule. Pick the first form. The agent does not need atmosphere. It needs verbs.
What Goes in CLAUDE.md
CLAUDE.md is the file Claude Code reads natively. The behavior is defined: when you launch Claude Code in a directory, the tool walks up the file tree from the current working directory to your home folder, collects every CLAUDE.md it finds along the way, and merges them in priority order with the more local file taking precedence. It does this without configuration. It does this every session.
The mental model: AGENTS.md is the file every agent reads. CLAUDE.md is the file Claude Code specifically reads, and which humans who use Claude often write to take advantage of Claude-specific behaviors. The two are not in conflict. They overlap, and most teams handle the overlap one of two ways.
Single source of truth for Claude. Contains everything AGENTS.md would contain, plus Claude-specific notes. AGENTS.md is a thin file that says "see CLAUDE.md plus the following non-Claude notes." Works well for repos where Claude is the primary agent and other tools are occasional.
AGENTS.md holds the universal context every agent needs. CLAUDE.md starts with a one-line "see AGENTS.md" and adds Claude-specific sections below. Works well for multi-agent shops where treating AGENTS.md as the universal file matters.
Pattern B is the more durable choice in 2026. The cross-tool convention is consolidating around AGENTS.md, and writing your universal context there means future agents you have not heard of yet will pick it up automatically. CLAUDE.md becomes the place for things that are genuinely Claude-specific.
What counts as Claude-specific? A few categories.
Model preferences. Which Claude model the project prefers for which task. "Use Opus 4.7 for architecture and refactoring; Sonnet 4.5 for routine edits and tests." If the project has a budget posture, name it.
Tool-use defaults. Which tools Claude should reach for first. "When debugging build errors, run pnpm build and read the actual output before guessing. When investigating a function, use the Read tool, not Grep, if you already know the file path." These are the lessons learned that you would otherwise repeat at the start of every session.
In-session memory hooks. If your team uses memory files, slash commands, or hooks, document them. "Memory lives in ~/.claude/projects/-path-encoded/memory/; the index file is MEMORY.md and you should read every file referenced from the index, not just the index itself."
Gotchas Claude has hit before. The single highest-payback section. Every time Claude makes the same mistake twice, the second occurrence costs more than the first because you trusted it more. Write the gotcha down. "Claude tends to add Tailwind v3 utility classes; this project is Tailwind v4 and the v3 classes silently fail to render." That one line saves a debugging session.
A typical CLAUDE.md following Pattern B looks like this.
# CLAUDE.md
See AGENTS.md for project structure, tech stack, build commands, and conventions.
## Claude-specific notes
### Model preferences
- Architecture, refactoring, planning: Claude Opus 4.7 (1M context)
- Routine edits, single-file changes, tests: Claude Sonnet 4.5
- Avoid Haiku for this codebase; the typing is too dense
### Tool-use defaults
- Use Read, not Grep, when the file path is known
- Run `pnpm build` before claiming a change builds; do not eyeball it
- For database changes, generate a migration via `pnpm db:generate`,
then read the generated file before committing
### Memory and slash commands
- Project memory: `~/.claude/projects/-var-www-storefront/memory/`
- Slash commands defined in `.claude/commands/`
- The `/release` command runs the full pre-deploy checklist;
prefer it over manual deploys
### Known gotchas
- Tailwind v4 only: do not use v3 utilities like `divide-y` without
the v4 modifier; check `tailwind.config.ts` if uncertain
- The Stripe webhook handler verifies signatures using a raw body
parser; do not switch to JSON middleware
- React 19's `use()` hook is in production; do not refactor to
`useEffect + useState` patterns
- Drizzle migrations are sequential; never edit a committed
migration file, only add new ones
Notice what the CLAUDE.md does not duplicate. It does not restate the project structure. It does not list the tech stack. It points to AGENTS.md and adds the layer that only matters when Claude is the agent. The file is shorter, denser, and more useful because it stays in its lane.
Other Variants in the Wild
Three other formats are still common enough that you will encounter them. Knowing what each one does, and when it loses to AGENTS.md, helps you avoid maintaining four files when one would do.
.cursorrules is Cursor's editor-specific format. It lives at the repo root, is plain text, and gets injected into every Cursor prompt automatically. The format is older than AGENTS.md and predates the cross-tool convention. Cursor now also reads AGENTS.md, but many existing repos still ship a .cursorrules file because it predates the standard. If you are starting fresh in 2026, write AGENTS.md and let Cursor pick it up. If you inherit a .cursorrules file, leave it in place and add AGENTS.md alongside; the two do not conflict.
.github/copilot-instructions.md is GitHub Copilot's path. The file is read by Copilot when it generates suggestions, including in the IDE and in pull request reviews. Copilot has been slower than Claude Code or Codex CLI to converge on AGENTS.md, and the .github/ path makes it organizationally distinct from a root-level file. The pragmatic move: keep .github/copilot-instructions.md if your team uses Copilot heavily, but make it a one-liner that says "see AGENTS.md" and leave the substance in the cross-tool file.
.aider/conventions.md is the aider tool's path for the same purpose. Aider is a CLI agent with a smaller footprint than Claude Code or Codex, but a loyal user base. The conventions file is read on every aider session. As of 2026, aider has added AGENTS.md support; the older path remains for backwards compatibility.
Cross-tool standard. Read by Codex CLI, Cursor, Sourcegraph Amp, aider (recent versions), Jules, and others. Repo root. Plain markdown. The default in 2026.
Claude Code's native file. Repo root, with hierarchical merging from CWD up to home folder. Plain markdown. Often a thin extension to AGENTS.md.
.cursorrules, .github/copilot-instructions.md, .aider/conventions.md. Older or tool-specific paths. In a new project, prefer AGENTS.md and let tools that read it do so. Keep tool-specific files only when the tool requires them.
The trend is clear. AGENTS.md is winning as the cross-tool standard. CLAUDE.md remains for Claude-specific extensions. Tool-specific files exist for backwards compatibility and for tools that have not adopted the cross-tool convention. Writing AGENTS.md first is the move that ages well.
One question that comes up repeatedly is whether to migrate existing tool-specific files into AGENTS.md or leave them alone. The honest answer is: leave them alone if the tool still requires them, but consolidate the substance. A repo with both .cursorrules and AGENTS.md does not need to duplicate content across both files. Pick one as the source of truth (AGENTS.md, in 2026), and let the other be a one-line pointer or a thin file that adds tool-specific notes only. The tools that read both will see the same effective rules. The tools that read only one will get what they need. The maintenance burden drops to a single file.
The same logic applies to organizations running multiple agentic tools simultaneously. Some teams use Claude Code for architecture and refactoring, Codex CLI for routine tasks, Cursor for in-editor work, and Copilot in pull request reviews. Maintaining four separate instruction files is the kind of overhead that kills the practice in month two. Maintaining one AGENTS.md, with thin tool-specific extensions only where genuinely necessary, is the kind of overhead the team can sustain. The cross-tool convention exists to prevent the maintenance bloat that would otherwise derail adoption.
How Agents Actually Discover and Use These Files
The discovery mechanism is simple by design. The agent reads from the current working directory upward, looking for known filenames. The first time a file is found, the agent stops walking. Or the agent collects every file along the way and merges them in priority order. The exact behavior depends on the tool, but the broad pattern is consistent.
For Claude Code specifically, the walk goes from CWD up to the user's home folder, collecting every CLAUDE.md it finds. The merge is hierarchical: a CLAUDE.md at ~/.claude/CLAUDE.md sets universal preferences, a CLAUDE.md at ~/projects/storefront/CLAUDE.md overrides for that project, a CLAUDE.md at ~/projects/storefront/packages/admin/CLAUDE.md overrides further for the admin package. The deeper file wins on conflicts.
For Codex CLI, the discovery is similar but the file it reads is AGENTS.md. The walk also goes from CWD up. The behavior of merging multiple files is more conservative; tools differ on whether they merge or pick the deepest.
For Cursor, the file lives at the repo root and is read on every prompt. Cursor does not walk up to the user's home folder by default, though it has added some support for inherited rules. AGENTS.md is read alongside .cursorrules.
The session begins in some directory. That is where discovery starts. If you launched the agent from a subpackage in a monorepo, the deepest file is the most local file.
The agent looks for known filenames at each level: AGENTS.md, CLAUDE.md, tool-specific files. It records what it finds. The walk stops at the user's home folder or at the filesystem root, depending on the tool.
Some tools merge every file found into a single context. Others pick the deepest file and stop. Claude Code merges; Codex CLI tends to pick. Read your tool's docs to know which.
The merged or selected content is prepended to the system prompt for the session. Every subsequent message in the conversation has this context available. The agent does not have to re-read it on each turn.
If the tool also reads a tool-specific file (like .cursorrules), that content is appended or merged according to tool rules. The principle: more specific wins, but the universal file always loads.
What happens when multiple files exist at the same level? Tools differ. Claude Code reads CLAUDE.md preferentially, even if AGENTS.md also exists, because CLAUDE.md is the tool's native file. Codex CLI reads AGENTS.md and ignores CLAUDE.md unless explicitly configured. Cursor reads both. The practical implication: write the universal context in AGENTS.md, write Claude-specific extensions in CLAUDE.md that reference AGENTS.md, and trust the tools to do the right thing.
One more discovery detail worth knowing: the user-level file. Most tools support a user-level instruction file in addition to the repo-level one. Claude Code reads ~/.claude/CLAUDE.md. Codex CLI has its own user config path. The user-level file is for things that apply to you across all projects: how you like the agent to talk to you, your tool preferences, your style rules. It is not for project context. Project context belongs in the repo, where every collaborator and every agent on the codebase sees the same thing.
The split between user-level and project-level is worth taking seriously. Mixing them is one of the more common failure modes. If your user-level file says "always use TypeScript strict mode," and you open a JavaScript codebase that does not, the agent now has conflicting instructions. The well-designed user-level file contains preferences that travel with you, not opinions about how a project should be built. "Be terse. Skip pleasantries. Always show me commands before running destructive ones." Those travel. "Always use TypeScript strict mode" does not.
The project-level file inverts the same principle. It contains opinions about how this specific codebase should be built. Those opinions live in the repo because they apply to anyone working on the repo, regardless of who they are. The agent reading them does not need to know which user it is serving. The user reading them does not need their personal preferences to be embedded in the project file. The two layers stay clean if you stay disciplined about which kind of statement belongs where.
One subtlety to watch: hierarchy precedence is not always intuitive. Some tools merge files top-down (root file applied first, deeper files override). Others merge bottom-up (deepest file applied first, root file fills gaps). Most do not document the behavior in detail. The pragmatic move is to test it: in a monorepo with a root AGENTS.md and a subpackage AGENTS.md, write a deliberately conflicting line in each and see which one the agent follows. Once you know your tool's behavior, you can structure the files to take advantage of it. Until you know it, do not assume.
Common Mistakes
The instruction file is a small piece of writing, but the failure modes are predictable. Six of them show up in nearly every team's first attempt.
Vague directives. "Write good code." "Follow best practices." "Be careful with the database." These instructions are not instructions. They are the agentic equivalent of "do your best." The agent already knows it should write good code. What it does not know is that "good code" in your codebase means using the existing query builder rather than introducing a new ORM, or that "best practices" in your team means React Server Components by default. Be specific. Name the pattern. Show the example.
Outdated information. The file ages with the project. Build sessions hit gotchas the file does not mention. Conventions evolve. Dependencies upgrade. Three months in, the AGENTS.md says you use Tailwind 3 when you migrated to 4 last week. The agent now actively misleads itself based on stale guidance. The instruction file is a living document. If it is not maintained, it becomes a liability.
Contradictions. Two sections that disagree. The "Tech stack" section says React 19, the "Conventions" section warns about React 18 patterns that no longer apply. The agent picks one and you do not know which. The fix is editorial: read the whole file when you change any part of it. Catch contradictions before the agent does.
Too long. A 4,000-word file gets skimmed. A 10,000-word file gets ignored. The instruction file is competing for context window space and for attention. Aim for around 200 useful lines. If you have more to say, link out to deeper docs. The instruction file is the table of contents, not the encyclopedia.
No "what NOT to do" section. The missing instruction is often the load-bearing one. Telling the agent what to do is necessary; telling it what not to do is what saves you from the failures you have actually experienced. "Do not edit files under src/generated/" is more valuable than three paragraphs about preferred coding style. Write the don'ts.
Writing for humans, not agents. The instruction file is read by both, but it is written for the agent first. That means short sentences, declarative tone, and no marketing language. "We are a passionate team building amazing experiences" is filler. "This is a Next.js storefront for selling print books" is information. The agent does not need atmosphere. It needs facts.
"Conventions: We follow modern best practices and write clean, maintainable code. Please ensure your contributions align with the team's high standards. Avoid anti-patterns."
The agent learns nothing. Every word here is filler. It does not know what your team considers an anti-pattern, what "modern best practices" means in this codebase, or what files to avoid touching.
"Conventions: Server components by default. Client components opt in with `'use client'`. All API routes validate inputs with Zod schemas in `src/server/schemas/`. Database access only through `src/db/queries/`; no raw SQL in route handlers. Do not edit `src/generated/` (regenerated from schema)."
The agent knows the default, the exceptions, the location of validation, the abstraction layer, and the file to avoid. Five lines, four operative rules.
The mistake that ties all of these together is treating the instruction file as a write-once artifact. It is not. It is a working document that earns its keep through maintenance. The first version is always rough. The fifth version is where it starts paying back the investment.
Two more failure modes are worth naming because they show up specifically in larger teams.
Personal opinions disguised as project conventions. One engineer prefers tabs. The instruction file says "use tabs for indentation," even though the project's .editorconfig says spaces. Three other engineers commit code with spaces because their editors honor .editorconfig. The agent reads the instruction file, indents with tabs, and produces a diff that fights the rest of the codebase. The fix is to keep personal opinions in user-level files and project-level statements in the project file, and to verify that project-level statements actually reflect the codebase rather than one author's taste.
Sections written by people who have never run the project. A product manager adds a paragraph about the deploy process based on a meeting from six months ago. A new engineer adds a tech-stack section without checking package.json. The instruction file accumulates plausible-sounding text that is wrong in subtle ways. The agent follows it, hits inconsistency, and you discover the error mid-session. The discipline is to verify any non-trivial change to the file by running the commands it documents. If the file says pnpm dev, run pnpm dev before merging the change. If the file lists a Postgres version, check the actual version. The verification is fast. The error it prevents is not.
Templates and Patterns
Three project shapes show up most often. Each one has a slightly different AGENTS.md skeleton. The patterns are not rigid; you will deviate based on your project's needs. But starting from a real-shape template is faster than starting from a blank file.
Web application skeleton. The most common shape. Frontend, backend, database, deploy target. The skeleton in the earlier section already shows this case. The principles to remember: name the framework version, list the actual commands you run, document the deploy trigger, and call out any local setup that is not obvious. If the agent has to know that you use a particular Postgres extension, write it down.
Library or SDK skeleton. Different from a web app. The build is a publish, not a deploy. The conventions are about API stability, semver discipline, and changelog hygiene. Tests matter more than dev servers. The skeleton looks like this.
# AGENTS.md
## What this is
A TypeScript SDK for the Example API. Published to npm as `@example/sdk`.
Used by both Node.js and browser environments. Public interface is stable;
breaking changes require major version bumps and migration notes.
## Project structure
- `src/` -- all source TypeScript
- `src/client.ts` -- main client class
- `src/resources/` -- per-resource API methods (one file per endpoint group)
- `src/types/` -- generated types from OpenAPI spec
- `tests/` -- Vitest unit tests
- `examples/` -- runnable usage examples
- `docs/` -- TypeDoc-generated reference
## Tech stack
- TypeScript 5.4 (strict, dual ESM + CJS output via tsup)
- Node.js 20+ supported; browsers via fetch polyfill
- Vitest 2.1 for testing
- Changesets for changelog and version management
## Build and deploy
- `pnpm build` -- produces ESM + CJS bundles in `dist/`
- `pnpm test` -- full test suite
- `pnpm test:watch` -- watch mode for development
- `pnpm typecheck` -- TypeScript-only check, no emit
- `pnpm changeset` -- author a changeset for the next release
- `pnpm release` -- CI-only command, do not run locally
- Publishing: `main` branch with a pending changeset triggers
Changesets release PR; merging that PR publishes to npm
## Constraints and conventions
- Public API: anything exported from `src/index.ts` is public and follows semver
- Internal helpers go in `src/internal/` and are not exported
- Do not edit `src/types/generated.ts`; regenerate via `pnpm types:generate`
- All public methods have JSDoc with at least one example
- Breaking changes require a major changeset and a migration note in CHANGELOG
- No runtime dependencies if avoidable; current dependency budget is 2 packages
- Tests cover happy path + at least two error cases per public method
## Documentation
- API reference: auto-generated, https://example.com/sdk/docs
- Examples: `examples/` directory, each with its own README
- ADRs: `docs/adr/`
## Related projects
- `example-api` repo: the API this SDK targets
- `example-cli` repo: CLI tool that consumes this SDK
- OpenAPI spec source: `example-api/openapi.yaml`
Notice the differences from the web app skeleton. The "Build and deploy" section is dominated by package commands, not server commands. The "Constraints" section is heavy on API stability and dependency hygiene because those are the load-bearing concerns for libraries. The "Project structure" calls out the public/internal split because that distinction is invisible from the file tree alone.
Monorepo skeleton. Different again. The root file is short and points to per-package files. Agents discovering the file in the root know the project shape; agents working in a specific package walk into that package's directory and find the package-specific file.
# AGENTS.md
## What this is
Monorepo for Example Inc. Three apps and four shared packages.
Turborepo manages the build graph; pnpm manages workspaces.
## Project structure
- `apps/web/` -- main customer-facing Next.js app (see apps/web/AGENTS.md)
- `apps/admin/` -- internal admin dashboard (see apps/admin/AGENTS.md)
- `apps/marketing/` -- Astro marketing site (see apps/marketing/AGENTS.md)
- `packages/ui/` -- shared React components
- `packages/db/` -- Drizzle schema and queries (single source of truth)
- `packages/auth/` -- auth client + server helpers
- `packages/config/` -- shared ESLint, TS, Tailwind configs
## Tech stack
- pnpm 9 (workspaces; lockfile is canonical)
- Turborepo 2.x (build graph, caching, remote cache via Vercel)
- TypeScript 5.4 (strict, project references across packages)
- Node 20+
## Build and deploy
- `pnpm install` -- install all workspaces
- `pnpm dev` -- runs `turbo dev` across all apps in parallel
- `pnpm build` -- builds the entire graph
- `pnpm test` -- runs all package tests
- Per-app commands: cd into the app and run its scripts
- Deploy: each app has its own Vercel project; pushes to `main` deploy
## Constraints and conventions
- All shared types live in `packages/db/src/schema.ts` or `packages/ui`
- Apps depend on packages, never on each other
- New packages: copy structure of `packages/ui` and register in
`pnpm-workspace.yaml`
- Versioning: apps are private; packages are versioned via Changesets
- Cross-package imports use `@example/` workspace aliases
## Per-app context
For app-specific guidance, read the AGENTS.md inside each app directory.
The root file covers the workspace; the app files cover the app.
## Documentation
- Root README: high-level overview
- ADRs: `docs/adr/`
- Internal wiki: https://wiki.example.com/engineering
## Related projects
- `example-infra` repo: Terraform for shared infrastructure
- `example-api` repo: separate Go API consumed by web and admin apps
The monorepo skeleton makes one structural choice explicit: the root file is the orientation, not the manual. Each app and each significant package has its own AGENTS.md with the app-specific or package-specific context. Agents discover the most local file, get the context they need, and ignore the rest. This pattern scales as the monorepo grows; trying to put every package's context in the root file does not.
Maintaining the File as the Project Evolves
The instruction file is a living document. The teams that get the most out of it treat it like a runbook: short, current, and updated whenever something changes. The teams that get the least out of it write it once, push it to main, and never touch it again. The first version is always wrong in subtle ways; only iteration makes it useful.
Five update triggers should cause you to open the file and edit it.
New dependency added. If the addition is significant (new framework, new ORM, new test runner), update the tech stack section. If it is minor (a small utility library), do not bother. The line is whether an agent operating on the codebase needs to know the addition exists.
New convention adopted. The team agreed in a code review that all forms should use a particular library. Three weeks later, half the codebase still uses the old approach. The fastest way to converge: write the convention into AGENTS.md immediately. Now every agent session enforces it without you having to repeat yourself.
New "do not touch" zone. A directory got auto-generated. A file got marked as managed by an external tool. A piece of legacy code was quarantined for a future rewrite. Each of these creates a new constraint. Document it before the next agent session.
Infra change. The deploy target moved. The database changed providers. The CI pipeline got rewritten. Update the build and deploy section. Agents that read stale infra notes will run the wrong commands and waste your time debugging the wrong problem.
Painful agent miss. The most important trigger. An agent made a mistake that was avoidable if the instruction file had said the right thing. The session is fresh, the context is loaded, the lesson is sharp. Update AGENTS.md right now, before closing the session, before the lesson fades. This is the "30-second update" pattern: in the time it takes to write a single sentence in the right section, you have permanently fixed the gap.
After every painful agent miss, update AGENTS.md before closing the session. Treat the file as the place where lessons accumulate. The discipline is not "write a perfect file"; it is "fix the file every time you find a gap." Over a few months, the file becomes the most accurate description of how the project actually works, written by the people and agents who actually work on it.
One pattern that compounds well: ask the agent to update the file. After a session where the agent learned something new about the codebase, finish with "update AGENTS.md to reflect what you learned." The agent writes the diff. You review it. The diff often catches conventions you would have forgotten to document yourself, because the agent felt the absence directly during the session. This works particularly well with Claude Code and Codex CLI, both of which are happy to edit instruction files when asked.
A second pattern: review the file in the same cadence as code review. When you do a quarterly architecture review, read AGENTS.md as part of the review. Cut sections that no longer apply. Add sections that should have been there. Update version numbers. The file is documentation, but it is documentation with a direct consumer; if it falls out of date, the consumer (the agent) suffers immediately, and so do you.
A third pattern: split the file when it grows past 200 lines. Move deep sections into linked docs. Keep AGENTS.md as the orientation; let the linked docs hold the depth. The agent that needs depth follows the link. The agent that needs orientation reads the orientation file and gets to work.
A fourth pattern, less common but powerful in teams that adopt it: pair the instruction file with an llms.txt. The llms.txt spec, proposed in late 2024, gives projects a way to publish a structured index of resources for AI consumption. AGENTS.md is the file the agent reads when working on the codebase; llms.txt is the file the agent reads when consuming the codebase as a documentation source. The two are complementary. A repo that ships both can be used by an internal agent (via AGENTS.md) and an external agent (via llms.txt) without either getting in the other's way. Linking from AGENTS.md to llms.txt is a small move that makes the connection explicit.
A fifth pattern, observed in shops that run agents heavily: a "session log" file alongside AGENTS.md. The session log is not for agents. It is for humans, and it captures the changes to AGENTS.md over time with a one-line note about why. "Added Tailwind v4 gotcha after Claude added a v3 utility class that silently failed." A few months in, the session log becomes a record of every painful agent miss the project has experienced. That record is useful for onboarding new team members, for retrospectives, and for noticing patterns that suggest the file needs structural changes rather than one more line.
The maintenance loop, run with discipline, also has a side effect that surprises people the first time it shows up: the project itself becomes more legible to humans. The file that started as a way to orient agents ends up being the document new engineers read first. The conventions that started as "things we tell the agent" turn into "things we agreed on as a team." The instruction file becomes the canonical answer to "how do we do things here," because it is the only document everyone (human and agent) actually reads. Teams that get this far stop thinking of AGENTS.md as an AI artifact. They think of it as the project's operating manual, with the side effect that agents read it too.
The Bottom Line
AGENTS.md is the cheapest engineering investment with the highest compounding return in agentic development. The file takes an hour to write the first time, ten seconds per session to update, and it pays back every time an agent operates on the codebase. The agent does not waste tokens reconstructing context that was sitting in the repo. You do not waste time explaining the same thing for the fifth time. The codebase becomes legible to any agent that touches it, and the team's accumulated knowledge becomes durable.
The convention is real, current, and stable. AGENTS.md is the cross-tool standard. CLAUDE.md is the Claude-specific extension. Tool-specific files exist for backwards compatibility. The pattern is simple, the discovery is automatic, and the maintenance discipline is light if you do it as you go. The teams that have figured this out work faster, ship safer, and pay less per session in tokens spent on context that should have been written down.
The deeper point is one about ratio of effort to return. A small artifact at the root of your repository is the difference between agents that orient in seconds and agents that flounder in minutes. The artifact is plain text. The artifact is version-controlled. The artifact compounds with every session. There are not many engineering investments that reliably pay off this fast and continue paying off indefinitely; this is one of them.
The corollary is that the practice rewards consistency more than ambition. A short, accurate, current AGENTS.md beats a long, comprehensive, slightly stale one every time. The discipline is to keep the file honest. The reward is that every agent session, for as long as the project lives, starts with the right context already loaded.
Spend the hour. Write the file. Keep it current. Stop wasting tokens explaining the same context to the same agent every time.
Drop AGENTS.md at your repo root today. Cover what the project is, where the files live, the tech stack, the build commands, the constraints, the related context. Add a CLAUDE.md only if you use Claude Code and have Claude-specific notes. Update both files every time an agent makes a mistake that the file should have prevented. That is the entire practice.
