The Problem
Your monorepo has a React frontend, a Python backend, a Go microservice, and shared packages. You create one CLAUDE.md at the root. Now Claude is confused: "Use TypeScript strict mode" when working on Python? "Follow Django patterns" when editing React? AI needs context, but giving it everything at once creates noise.
The issue: Monorepos have different rules for different packages. A single config file forces you to choose between too generic (useless) or too detailed (overwhelming).
Different parts of your codebase need different guidance. The web app follows React conventions, the API follows Flask patterns, shared libraries have their own rules. AI should know where it is and what applies.
The Core Insight
Organize configuration hierarchically: root level for shared conventions, package level for specific rules. AI traverses up the tree, inheriting and overriding as needed.
Think of it like CSS specificity: root config applies everywhere (like *), package config applies to that package (like .class), and more specific configs override less specific ones.
The Hierarchy Pattern
Level 1: Root Configuration (Universal Rules)
At repo root, define only what applies to EVERYTHING:
# /CLAUDE.md
## Monorepo Overview
This is a monorepo containing multiple applications and packages.
**Monorepo Tool:** pnpm workspaces
**Node Version:** 20.x
**Package Manager:** pnpm (NOT npm or yarn)
## Global Conventions
- **Git:** Conventional Commits (feat:, fix:, docs:, etc.)
- **Testing:** Each package has its own test setup
- **Linting:** Configured per package (see package-specific CLAUDE.md)
- **CI/CD:** GitHub Actions in `.github/workflows/`
## Workspace Structure
```
apps/
web/ # Next.js frontend (see apps/web/CLAUDE.md)
api/ # Express API (see apps/api/CLAUDE.md)
admin/ # Admin dashboard (see apps/admin/CLAUDE.md)
packages/
ui/ # Shared UI components (see packages/ui/CLAUDE.md)
utils/ # Shared utilities
types/ # Shared TypeScript types
```
## Global Commands
```bash
# Install dependencies (run from root)
pnpm install
# Run specific workspace
pnpm --filter web dev
pnpm --filter api dev
# Run all workspaces
pnpm dev
# Build all
pnpm build
# Test all
pnpm test
```
## Important Rules
1. **NEVER install at root level** unless it's a dev dependency shared by all packages
2. **Use workspace protocol** for internal packages: `"@repo/ui": "workspace:*"`
3. **Each app/package has its own CLAUDE.md** - refer to those for specifics
4. When working in a package, ALWAYS read its CLAUDE.md first
Level 2: Application Configuration (App-Specific)
Each app gets its own config that extends root:
# /apps/web/CLAUDE.md
## Web App (Next.js Frontend)
**Inherits:** `/CLAUDE.md` (monorepo global rules)
**Extends:** This file adds web-specific conventions
## Stack
- **Framework:** Next.js 14 (App Router)
- **Language:** TypeScript 5.3
- **Styling:** Tailwind CSS
- **State:** Zustand + React Query
- **UI Components:** From `@repo/ui` package
- **Types:** From `@repo/types` package
## Local Commands
```bash
# From repo root:
pnpm --filter web dev # Start dev server
pnpm --filter web build # Build for production
pnpm --filter web test # Run tests
# From apps/web/:
pnpm dev
pnpm build
pnpm test
```
## Conventions
### Importing Internal Packages
```typescript
// Always use alias imports:
import { Button } from '@repo/ui'
import { type User } from '@repo/types'
// NOT relative paths across workspaces:
// import { Button } from '../../../packages/ui/src/Button' ❌
```
### Component Structure
```
src/
app/ # Next.js App Router pages
components/ # Web-specific components (NOT shared ones)
lib/ # Web-specific utilities
styles/ # Global styles
```
**Key Rule:** If a component could be used by `admin` app, it belongs in `@repo/ui`, not here.
## Anti-Patterns
- ❌ **DON'T** duplicate components from `@repo/ui`
- ❌ **DON'T** import from other apps (only from `packages/`)
- ❌ **DON'T** put shared types here (use `@repo/types`)
Level 3: Package Configuration (Library-Specific)
# /packages/ui/CLAUDE.md
## Shared UI Package
**Inherits:** `/CLAUDE.md` (monorepo global rules)
**Extends:** This file adds UI package conventions
## Purpose
Shared React components used by `web` and `admin` apps.
## Stack
- **React:** 18.x (no Next.js specifics)
- **TypeScript:** Strict mode
- **Styling:** Tailwind CSS (apps import classes)
- **Build:** tsup for bundling
- **Storybook:** For component development
## Commands
```bash
pnpm --filter @repo/ui dev # Storybook dev server
pnpm --filter @repo/ui build # Build package
pnpm --filter @repo/ui test # Run tests
```
## Component Guidelines
### Creating New Components
1. **Must be framework-agnostic** (works in Next.js and vanilla React)
2. **No app-specific logic** (no auth checks, no routing)
3. **Documented in Storybook**
4. **Fully typed with TypeScript**
### Component Template
```typescript
// src/components/Button.tsx
import { type ButtonHTMLAttributes } from 'react'
export interface ButtonProps extends ButtonHTMLAttributes {
variant?: 'primary' | 'secondary' | 'outline'
size?: 'sm' | 'md' | 'lg'
}
export function Button({
variant = 'primary',
size = 'md',
children,
...props
}: ButtonProps) {
return (
)
}
```
### Exports
```typescript
// src/index.ts
export { Button, type ButtonProps } from './components/Button'
export { Card, type CardProps } from './components/Card'
// ... etc
```
## Anti-Patterns
- ❌ **DON'T** import from Next.js (`next/link`, `next/image`, etc.)
- ❌ **DON'T** use hooks that depend on app context (auth, routing)
- ❌ **DON'T** include app-specific business logic
- ❌ **DON'T** make network requests (components are pure UI)
## Testing
- Test components in isolation
- Use Testing Library
- Mock all external dependencies
- Aim for 80%+ coverage
How AI Uses the Hierarchy
When AI works in /apps/web/src/components/Header.tsx:
- Reads
/CLAUDE.mdfor global monorepo rules - Reads
/apps/web/CLAUDE.mdfor web-specific conventions - Combines both contexts, with more specific (web) overriding general (root)
When AI works in /packages/ui/src/Button.tsx:
- Reads
/CLAUDE.mdfor global rules - Reads
/packages/ui/CLAUDE.mdfor UI package conventions - Knows this is a shared component, so no app-specific code allowed
Teaching AI The Hierarchy
In each package's CLAUDE.md, start with: "Inherits: /CLAUDE.md" and "Extends: This file adds [package]-specific rules." This explicitly tells AI to read root config first, then apply local overrides.
Cross-Package Dependencies
Document how packages interact:
# /CLAUDE.md (root)
## Package Dependencies
**Dependency Rules:**
- Apps CAN depend on packages
- Packages CAN depend on other packages
- Apps CANNOT depend on other apps
- Packages SHOULD minimize cross-package dependencies
**Dependency Graph:**
```
apps/web → packages/ui → (no deps)
→ packages/types → (no deps)
→ packages/utils → (no deps)
apps/api → packages/types → (no deps)
→ packages/utils → (no deps)
packages/ui → packages/types ← (shared dependency)
```
**Adding Dependencies:**
```bash
# Add to specific workspace
pnpm --filter web add lodash
pnpm --filter @repo/ui add react
# Add to root (dev deps only)
pnpm add -D -w typescript
```
Avoiding Configuration Bloat
Root: Keep It Minimal
Root CLAUDE.md should be < 100 lines. Only include:
- Monorepo structure overview
- Global commands (install, test all, build all)
- Cross-cutting concerns (git conventions, ci/cd)
- Pointers to package-specific configs
Package: Be Specific
Package CLAUDE.md should be focused on that package's concerns:
- What makes THIS package different
- Dependencies and imports
- Package-specific commands
- Boundary rules (what belongs here vs elsewhere)
The Duplication Trap
Don't copy the same rules to every package config. If it applies to all packages, put it in root. If it only applies to React packages, maybe you need a `REACT.md` that multiple packages reference.
Alternative Patterns
Pattern: Shared Template Files
# Create shared config for common patterns
/.ai/
templates/
REACT_APP.md # Template for React apps
SHARED_PACKAGE.md # Template for shared packages
# Reference from package configs:
# /apps/web/CLAUDE.md
## Stack
See `/.ai/templates/REACT_APP.md` for base React app conventions.
**Web-specific additions:**
- Uses Clerk for auth
- Deploys to Vercel
- ...
Pattern: Config Composition
# /apps/web/CLAUDE.md
**Inherits (in order):**
1. `/CLAUDE.md` - Global monorepo rules
2. `/.ai/templates/REACT_APP.md` - React app conventions
3. This file - Web-specific overrides
## Web-Specific Overrides
[Only what's unique to web app]
Quick Reference
Monorepo Config Structure:
/CLAUDE.md # Global rules (< 100 lines)
/apps/web/CLAUDE.md # Web app (inherits root)
/apps/api/CLAUDE.md # API (inherits root)
/packages/ui/CLAUDE.md # UI package (inherits root)
/.ai/templates/ # Optional: shared templates
Root CLAUDE.md Should Include:
- Monorepo tool (pnpm, yarn, nx, turborepo)
- Workspace structure (apps/, packages/)
- Global commands (install, test all, build all)
- Cross-package rules (how packages interact)
- Pointers to package-specific configs
Package CLAUDE.md Should Include:
- "Inherits: /CLAUDE.md" at the top
- Package purpose and scope
- Stack (only what's different from root)
- Local commands (dev, build, test for this package)
- Import patterns (how to use this package)
- Boundary rules (what belongs here vs elsewhere)
Commands to Document:
# Root level:
pnpm install # Install all dependencies
pnpm dev # Run all apps in dev mode
pnpm build # Build all packages
pnpm test # Test all packages
# Package level:
pnpm --filter web dev # Run specific workspace
pnpm --filter @repo/ui build # Build specific package
Anti-Patterns to Avoid:
- ❌ Duplicating root rules in every package config
- ❌ Creating CLAUDE.md for every tiny package
- ❌ Root config over 200 lines (too much detail)
- ❌ Package configs that don't reference root
- ❌ No guidance on cross-package dependencies