Multi-Repo

Monorepo vs Multi-Repo: How to Manage AI Rules in Both

Different architectures need different rule strategies. Here's how to structure CLAUDE.md for monorepos and multi-repo setups.

8 min readยทMay 28, 2025

Monorepo or multi-repo โ€” each needs a different AI rules strategy

Hierarchical files vs centralized sync: pick the pattern that fits

Two Architectures, One Problem

Whether your team uses a monorepo or multiple repositories, the core challenge is the same: how do you ensure consistent AI coding standards across every part of your codebase? The answer depends on your architecture, because monorepos and multi-repo setups have fundamentally different file structures, tooling, and workflows.

In a monorepo, everything lives in one repository โ€” frontend, backend, shared libraries, infrastructure. The challenge is scope: how do you give the AI different rules for different parts of the codebase within a single repo? In a multi-repo setup, each service or project has its own repository. The challenge is sync: how do you keep rules consistent across dozens of independent repos?

Both architectures have well-established patterns. This guide covers each one, so you can pick the approach that matches your setup โ€” or use both if you're transitioning between architectures.

Monorepo Strategy: Hierarchical Rules

Claude Code's hierarchical CLAUDE.md support is purpose-built for monorepos. You place a root CLAUDE.md at the repository root with global rules (security, naming conventions, testing standards), then add subdirectory-specific files that extend or override the root for each package or module.

For example, a typical monorepo might have: root CLAUDE.md with universal rules, packages/frontend/CLAUDE.md with React and Tailwind conventions, packages/api/CLAUDE.md with Express and database patterns, and packages/shared/CLAUDE.md with library-specific constraints. When the AI works in packages/frontend/, it merges the root rules with the frontend rules automatically.

The key principle is: global rules at the root, specific rules at the leaves. Don't repeat rules in subdirectory files that already exist in the root. Subdirectory files should only contain rules that are specific to that part of the codebase or that override a root rule for a good reason.

  • Root CLAUDE.md: Security, naming, testing standards (applies everywhere)
  • packages/frontend/CLAUDE.md: React, Tailwind, component patterns (extends root)
  • packages/api/CLAUDE.md: Express, database, API response patterns (extends root)
  • packages/shared/CLAUDE.md: Library constraints, no framework dependencies (extends root)
๐Ÿ’ก Monorepo Pattern

Global rules at the root, specific rules at the leaves. Don't repeat root rules in subdirectory files โ€” subdirectory CLAUDE.md should only add or override, never duplicate.

Monorepo Pitfalls to Avoid

The most common monorepo mistake is putting everything in the root file. A 300-line CLAUDE.md that covers React, Express, Python scripts, and infrastructure-as-code is too long and too scattered. The AI processes it as one giant context block, diluting the impact of rules that only matter in specific parts of the codebase.

The second pitfall is contradictory rules across layers. If the root says 'Use named exports' but the frontend file says 'Use default exports for pages,' the AI may behave inconsistently. When overriding a root rule, be explicit: 'Override root: Use default exports for Next.js page components only.'

Third, don't create subdirectory rules files for directories that don't need them. A utility library with 3 files doesn't need its own CLAUDE.md. Only create subdirectory files when the AI consistently makes mistakes that the root rules don't address.

Multi-Repo Strategy: Centralized Sync

In a multi-repo setup, each repository has its own CLAUDE.md at the root โ€” but maintaining those files independently is the copy-paste drift problem. The solution is centralized rule management: define rulesets once, then sync them to each repo.

The composable ruleset model works naturally with multi-repo architectures. Define a base ruleset with universal standards, then create stack-specific rulesets (nextjs-standards, python-standards, go-standards). Each repo selects the rulesets that apply to its stack, and the CLI composes them in order.

The sync happens through a CLI command in each repo: rulesync-cli pull fetches the assigned rulesets, composes them, and writes the output file. Add this to CI/CD or postinstall and every repo stays current automatically. When you update a rule centrally, every repo picks up the change on the next sync.

  1. 1Create base ruleset: universal standards (security, naming, testing)
  2. 2Create stack rulesets: one per framework/language your org uses
  3. 3Assign rulesets to each repo via the dashboard or .rulesync.json
  4. 4Run rulesync-cli pull in each repo (or add to CI/postinstall)
  5. 5Update rules centrally โ€” all repos sync on next pull
โœ… Multi-Repo Pattern

Base ruleset + stack ruleset + team overrides, composed in order. One CLI command per repo syncs everything. Add to CI/postinstall for zero-touch consistency.

Multi-Repo: Handling Team-Specific Overrides

Not every multi-repo team wants identical rules. Your data engineering team might have different testing conventions than your frontend team. The payments team might have stricter security rules than the internal tools team.

Composable rulesets handle this naturally: base standards + stack-specific + team overrides. The team override ruleset is the most specific layer โ€” it adds or modifies rules for a particular team's needs without affecting anyone else's repos.

The ordering matters: base is applied first, then stack-specific, then team overrides. Later rulesets override earlier ones for conflicting rules. This means a team can relax a base rule (with a good reason) or tighten it without creating a separate copy of the entire base ruleset.

Choosing the Right Approach

If you're in a monorepo: use hierarchical CLAUDE.md files. Root for global rules, subdirectory files for module-specific rules. No external tooling required โ€” it's built into how Claude Code processes rule files.

If you're in multi-repo: use centralized sync with composable rulesets. The per-repo overhead is minimal (one config file, one CLI command), and the benefit of consistent rules across all repos compounds with every repo you add.

If you're in a hybrid (some monorepos, some standalone repos): use both. Hierarchical rules within each monorepo, centralized sync across all repos. The sync tool writes the root CLAUDE.md for each repo; subdirectory files are managed within the repo by the teams that own those modules.

If you're transitioning from multi-repo to monorepo (or vice versa): start with the approach that matches your current architecture. Migrate the rule management strategy when you migrate the code. The rules themselves โ€” the actual content โ€” transfer cleanly between approaches.

โ„น๏ธ Hybrid Works Too

If you have both monorepos and standalone repos, use hierarchical rules within each monorepo and centralized sync across all repos. The approaches compose cleanly.

Monorepo vs Multi-Repo: How to Manage AI Rules in Both โ€” RuleSync Blog