Guides

Setting up Claude Code in a monorepo

One root CLAUDE.md covering every package either grows until it's mostly noise, or stays generic enough to be useless. Claude Code has native support for splitting instructions, commands and skills by directory, so a session working in packages/api/ never loads the frontend's conventions.

How CLAUDE.md loads across directories

Claude Code loads every CLAUDE.md from your working directory and each parent directory at launch. Files in subdirectories below that load on demand, the first time Claude reads a file in that directory.

monorepo/
  CLAUDE.md              # rules that apply everywhere
  packages/
    api/
      CLAUDE.md           # API-specific conventions
      .claude/skills/
    web/
      CLAUDE.md           # frontend-specific conventions
      .claude/skills/
    shared/
      CLAUDE.md

Root CLAUDE.md holds repo-wide rules:

Run package scripts from the package directory, not the monorepo root.
Prefix commit subjects with the package name, e.g. `api: add rate limiting`.
Never edit files under packages/*/generated/. Run `npm run codegen` in the package instead.

Each package's own CLAUDE.md adds what only applies there, for example packages/api/CLAUDE.md:

Copy `.env.example` to `.env` before running anything. Tests fail without it.
Write queries with the Knex query builder. Never put raw SQL in route handlers.

See the CLAUDE.md template guide for what belongs in these files versus what to leave out.

Where you start Claude matters

Start fromFile accessCLAUDE.md loaded at launch
Repo rootEvery fileRoot only; package files load on demand as Claude reads there
A package directoryThat subtree, until you grant moreThat package's plus every ancestor's

Run /context in a session and check Memory files to confirm which CLAUDE.md files actually loaded.

Per-package commands

Don't try to make one root command work for every package. State the rule once at the root ("run scripts from the package directory") and let each package's CLAUDE.md list its own copy-pasteable commands:

## Commands (run from packages/api/)
- Dev: `npm run dev`
- Test one file: `npm test -- src/__tests__/routes/users.test.ts`
- Migrate: `npm run migrate`

Scope skills per package

A skill in packages/api/.claude/skills/ loads only when Claude works on files in that package. Frontend work never pulls in API testing conventions:

---
name: api-testing
description: Testing patterns for the API package. Use when writing or
  modifying tests in packages/api/.
---

- All tests: `npm test`
- Single file: `npm test -- <path>`
- Wrap database tests in a transaction that rolls back.

To scope a skill by file pattern instead of location, put it in the repo root's .claude/skills/ and add a paths field to its frontmatter, e.g. paths: ["**/migrations/**"] for a migrations skill that should apply wherever that path shows up. If you start Claude from the repo root and it touches many packages in one session, skills from every package it visits accumulate, so keep descriptions short and lead with the words a request would actually contain. See the skills guide for description-writing tips.

Keep other packages out of context

Starting from the root means another team's CLAUDE.md loads the moment Claude reads a file there. Exclude packages you never touch with claudeMdExcludes in .claude/settings.local.json:

{
  "claudeMdExcludes": [
    "**/packages/legacy-*/**"
  ]
}

Going the other way, a task that spans packages, like updating a shared type used by both api and web, needs explicit access when you start from a single package directory. Grant it per-session with --add-dir, or commit it for the team in that package's .claude/settings.json:

{
  "permissions": {
    "additionalDirectories": ["../shared"]
  }
}

See the settings.json guide for where these files live and how scopes layer. If a package also needs a PreToolUse hook, like blocking risky commands in a deploy package, the free hook builder is a fast way to write and test the matcher before committing it.

Skip the setup: get the tested versions

Keelwork bundles 10 workflow skills, 5 tested safety hooks (including a full guard-bash and a secret scanner), 3 subagents and 5 CLAUDE.md templates, with a one-command installer that safely merges into your settings.

Get Keelwork — $24 →