How to Structure a Monorepo for AI Coding Agents

A two-tier AGENTS.md pattern, concrete directory conventions, and a worked example tree that keep an AI coding agent's context scoped to the package it's actually working in.

Carlo Zuercher
Carlo Zuercher
Staff Engineer, Platform
12 August 20261 min read

How to structure a monorepo for AI coding agents comes down to one working pattern: a root AGENTS.md with repo-wide rules, plus a nested AGENTS.md inside every package covering that package's stack, commands, and boundaries. Agents from Codex to Cursor to Claude Code read the nearest file in the directory tree and treat it as authoritative for that location, so where a file lives controls an agent's behavior more reliably than anything typed into a prompt. Get that placement right and an agent working in packages/api never wastes context loading instructions or code that belong to packages/web.

Why a bigger repo makes agents worse, not smarter

More code doesn't mean more useful context, it means more noise. An agent that loads one root-level instructions file covering four or five unrelated stacks spends tokens on rules that don't apply to the file it's editing, and every irrelevant paragraph competes for space with the actual task. Anthropic's own guidance on large codebases puts it plainly: as a codebase grows, the defaults tuned for smaller projects can fill the context window with instructions and file reads unrelated to the task, costing tokens and degrading performance.

The fix isn't a smaller repo, it's smaller context per task, and that's a structure problem, not a prompting problem. A single root file covering four different stacks spends most of its length on rules that are irrelevant to any one edit, and the agent still has to read through all of it before it can start on the actual task. Directory-level scoping is one of the more mechanical levers in the broader set of ai coding tools techniques, and it tends to pay off faster than prompt tuning does.

How to structure a monorepo for AI coding agents: the two-tier AGENTS.md pattern

The pattern comes from the AGENTS.md specification, the open format that Codex, Cursor, Copilot, Gemini CLI, Aider, Windsurf, and dozens of other agents read natively: a root AGENTS.md for repo-wide rules, then a nested AGENTS.md inside each package for anything specific to that package. Agents automatically read the nearest file in the directory tree, so the closest one takes precedence and every subproject can ship tailored instructions. This isn't theoretical. OpenAI's own main repository runs 88 separate AGENTS.md files, one per meaningful subproject, according to the format's own documentation.

The convention also has real adoption behind it. More than 60,000 open source projects use AGENTS.md, and it's read natively by more than 20 coding agents. That's worth knowing before inventing a custom convention of your own: a file that follows the standard shape works for whichever agent a teammate or contributor happens to run, instead of a bespoke format only one tool understands. If you haven't written the base file yet, the mechanics of doing that are covered in how to write an AGENTS.md file.

Directory conventions that keep an agent inside its lane

  • One AGENTS.md per deployable unit, not per folder. A package that ships as its own service, app, or library gets a file. A folder of shared types tucked inside another package usually doesn't need one.

  • Keep packages flat under packages/ or apps/. Don't nest a package inside another package's src/, since that breaks the nearest-file logic an agent relies on to find the right instructions.

  • Name packages by domain (api, billing, worker) rather than by layer (backend, utils, common). An agent scanning package names for relevance matches domain words faster than generic layer names.

  • Colocate tests with the source they test inside the same package, and state the test command in that package's AGENTS.md rather than only in a root-level CI config file.

  • Give shared code, meaning types, UI primitives, or utilities that two or more packages import, its own package with its own AGENTS.md, instead of letting every consumer duplicate or reinterpret it.

  • Avoid burying packages more than two or three directories deep. Deeper nesting means an agent has to walk further up the tree before it finds a file at all, and tooling that discovers nested files by glob pattern gets slower and messier the deeper it has to search.

A worked example: a three-package monorepo

Here's how that looks for a small SaaS codebase with an API, a frontend, a background worker, and a shared package:

monorepo/
  AGENTS.md                     # repo-wide rules, package map, shared commands
  package.json
  turbo.json
  packages/
    api/
      AGENTS.md                 # Node/Express stack, DB rules, run commands
      src/
        routes/
        db/
        __tests__/
      package.json
    web/
      AGENTS.md                 # React/Vite conventions, component patterns
      src/
        components/
        __tests__/
      package.json
    worker/
      AGENTS.md                 # queue conventions, retry rules, run commands
      src/
        jobs/
        __tests__/
      package.json
    shared/
      AGENTS.md                 # types and utils shared across packages
      src/
      package.json

Every package under packages/ that ships independently gets its own AGENTS.md. shared/ gets one too, because agents editing api/ or worker/ need to know what they're allowed to change in code that three other packages import. Nothing below src/ inside a package needs its own file unless that subdirectory has genuinely different rules of its own, such as a migrations/ folder with strict do-not-edit-by-hand conventions.

What belongs in the root file versus each package's file

The root file orients an agent to the whole repo. Each package's file answers questions specific to that package's stack. Splitting the two cleanly is what keeps either file from growing into a document nobody reads in full.

Location

Typical contents

Root AGENTS.md

Repo map of which package does what, monorepo tool commands such as turbo run build --filter=api, cross-cutting conventions like commit format and review expectations, and a one-line pointer to each package's own file.

Package AGENTS.md

Exact run, test, and lint commands for that package, framework and library specifics, database or queue rules, known gotchas, and explicit boundaries on files the agent shouldn't touch without asking.

Scoping tools so an agent can't wander into the wrong package

Clean directory boundaries only help if the tool you're running actually respects them. Claude Code, for example, lets you exclude a specific package's memory file with the claudeMdExcludes setting, grant read and write access to a sibling package with additionalDirectories, and block reads of generated or vendored code with Read deny rules in permissions.deny, all documented in Anthropic's guide to setting up Claude Code in a monorepo. None of that replaces good directory structure, it only works because the packages are already separated cleanly enough for path-based rules to target them.

Where you start an agent's session matters just as much as which rules it loads. Starting from a package directory scopes file access to that subtree by default, while starting from the repo root gives an agent access to everything and relies on excludes and deny rules to keep it out of packages it shouldn't touch. How much control you get over that starting point differs between a terminal-based agent and one built into an IDE, which is covered in terminal vs IDE AI coding agent.

Running multiple agents across packages without collisions

When more than one agent runs at a time, one agent per package is the safest split, because it maps directly to the directory boundaries already in place. Overlapping writes are the real risk, not context size, so file ownership matters as much as file organization. The mechanics of running several agents at once, including worktrees, branch isolation, and merge order, are covered in running multiple AI coding agents in parallel. The directory conventions here are what make that approach safe in the first place: if packages/api and packages/web never share files outside packages/shared, two agents can work on them at the same time without racing on the same lines of code.

Keeping nested AGENTS.md files from going stale

A nested file that's wrong is worse than no file, because an agent trusts it by default and won't second-guess a command that no longer exists. Treat AGENTS.md edits like any other documentation change: review them in the same pull request as the code change that made them necessary, and revisit them after a major model upgrade, since instructions written to work around an older model's limitation can become dead weight once a newer model handles the case natively. This is a narrower, structural version of the broader problem covered in how to keep an AI coding agent from losing context, scoped specifically to where files live rather than to the symptoms of a full context window.

Don't forget the CI checkout

Local development isn't the only place nested files matter. If a pipeline runs an agent for automated review or a scoped coding task, check that the checkout step actually pulls each package's AGENTS.md along with its source, especially if sparse or shallow checkouts are being used to keep CI fast. A checkout that skips a package's nested file silently reverts that agent to the root file's generic rules for a task that needed package-specific ones. The setup steps for wiring an agent into CI safely are covered in how to run an AI coding agent in CI.

Frequently asked questions

Should every package in a monorepo have its own AGENTS.md file?

Only packages that ship independently or that agents work in regularly need one. A small internal config package with a handful of files rarely needs its own, the root file's coverage is enough. A package with its own framework, database layer, or deploy process should almost always get one, because that's exactly the context a generic root file can't provide without becoming bloated.

What's the difference between AGENTS.md and CLAUDE.md?

AGENTS.md is the vendor-neutral, open-standard file that Codex, Cursor, Copilot, Gemini CLI, and most other coding agents read natively. CLAUDE.md is Claude Code's own memory file, predates the AGENTS.md standard, and is what Claude Code reads by default. Teams that want both to work from one source typically symlink AGENTS.md to CLAUDE.md, or use an import line inside CLAUDE.md that pulls in AGENTS.md's contents, rather than maintaining two files that can drift apart.

How many nested AGENTS.md files is too many?

There's no fixed ceiling. OpenAI's own monorepo runs 88 of them without apparent trouble. The practical limit is whether each file still earns its place: if a package's file just repeats the root file in different words, merge it back up. If two sibling packages' files are identical, that's usually a sign the packages should share one file, or be one package.

Should generated code and build output be excluded from what an agent reads?

Yes. Directories like dist/, build/, and node_modules/ add tokens without adding useful context, and most agents skip anything already listed in .gitignore by default. For committed-but-generated code or a vendored SDK that isn't gitignored, an explicit deny rule, such as Claude Code's Read deny rules, keeps an agent from opening those files even when a search turns them up.

Does this structure work for a large single-tree codebase that isn't a formal monorepo?

Yes. The pattern doesn't require separate packages with their own package.json files. Nest AGENTS.md files under major subsystem directories, such as src/api/ or src/db/, the same way they'd sit under packages/api/. An agent still reads the nearest file up the directory tree regardless of whether that directory is a formally published package or just a subsystem folder.

How did this land?

About the author

Carlo Zuercher
Carlo Zuercher

Staff Engineer, Platform

Carlo works on the platform that turns prompts into running apps. He writes the engineering deep dives and the changelog notes worth reading.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.