Your monorepo has 200 packages, 15 teams, and a shared infrastructure layer that everything depends on. A developer changes a utility function in the shared layer. The PR looks small — 12 lines changed. But that function is imported by 47 packages across 8 teams, and the behavioural change will break three of them in ways that won't show up until their next deployment.
This is the monorepo review problem: small changes can have outsized, invisible impact. And traditional code review tools have no way to surface that impact before merge.
Why monorepo review is different
In a polyrepo world, the blast radius of a change is contained to the repository it lives in. Change a function, run the tests in that repo, get a review from the team that owns it. Simple.
Monorepos collapse this isolation. A single PR can touch shared code that affects every team in the organisation. The challenges are specific:
- Cross-package impact — a change to a shared utility can break consumers that aren't tested in the PR's CI scope
- Ownership ambiguity — who reviews a change that touches packages owned by three different teams?
- Inconsistent standards — different packages may have evolved different conventions, and a PR that crosses boundaries needs to respect both
- Review routing — the right reviewer depends on which packages are affected, not just which files are changed
- CI cost — running every package's test suite on every PR is prohibitively expensive; selective testing requires understanding impact
How autter solves monorepo review
autter is built with monorepo-scale codebases in mind. It understands package boundaries, dependency graphs, and cross-package impact — and uses this understanding to make review faster, safer, and more accurate.
Cross-package impact analysis
When a PR modifies shared code, autter traces the dependency graph to identify every affected consumer:
// autter impact analysis for PR #3847
// Changed: packages/shared/utils/format-currency.ts
//
// Direct consumers (7 packages):
// packages/checkout/src/components/PriceDisplay.tsx
// packages/invoicing/src/generators/pdf.ts
// packages/reporting/src/charts/revenue.ts
// packages/admin/src/views/billing.tsx
// packages/api/src/routes/pricing.ts
// packages/mobile/src/screens/Cart.tsx
// packages/email/src/templates/receipt.ts
//
// Behavioural change detected:
// format-currency() now rounds to 2 decimal places (was 0)
// This changes output for all consumers.
//
// At-risk consumers (3 packages):
// ⚠ packages/invoicing — tests compare exact string output
// ⚠ packages/reporting — snapshot tests will break
// ⚠ packages/api — API response format change (breaking)
This analysis happens in seconds — before any CI runs, before any reviewer looks at the PR.
Intelligent review routing
In a monorepo, the right reviewer isn't always the person who owns the files being changed — it's the person who owns the packages being affected. autter handles this automatically:
# autter.config.yml
monorepo:
# Define package ownership
ownership:
- path: "packages/checkout/**"
team: "@checkout-team"
- path: "packages/invoicing/**"
team: "@billing-team"
- path: "packages/shared/**"
team: "@platform-team"
# Review routing rules
routing:
# Changes to shared code: require platform team + affected teams
shared_code:
paths: ["packages/shared/**"]
require:
- team: "@platform-team" # owns the code
- affected_teams: true # auto-add affected package owners
# Cross-package changes: require all affected teams
cross_package:
require:
- affected_teams: true
- min_reviewers: 1 # per affected teamWhen the format-currency PR is opened, autter automatically requests reviews from @platform-team (owns the shared code), @billing-team (invoicing affected), @reporting-team (reporting affected), and @api-team (API affected).
Per-package standards
Different packages in a monorepo often have different conventions — the React frontend uses different patterns than the Go backend, which uses different patterns than the shared TypeScript utilities. autter supports per-package rule configuration:
# packages/checkout/.autter.yml (overrides root config)
rules:
react:
enforce_hooks_rules: true
require_memo_for_list_items: true
testing:
require_rtl: true # React Testing Library
min_coverage: 85%
# packages/api/.autter.yml
rules:
api:
require_openapi_update: true # API changes must update the spec
require_migration: true # Schema changes need migrations
testing:
require_integration_tests: true
min_coverage: 90%Selective CI recommendations
Running every package's test suite on every PR is expensive. autter's impact analysis tells your CI exactly which packages need testing:
# GitHub Actions example
- name: Determine affected packages
id: affected
run: npx autter impact --format json > affected.json
- name: Test affected packages
run: |
PACKAGES=$(jq -r '.affected_packages[]' affected.json)
for pkg in $PACKAGES; do
npm test --workspace=$pkg
doneThis reduces CI time from "run everything" (45+ minutes in a large monorepo) to "run what's affected" (typically 5-15 minutes).
Change categorisation
autter categorises monorepo changes by their scope and risk:
| Category | Description | Review requirement |
|---|---|---|
| Package-local | Changes contained within one package | Package owner |
| Cross-package | Changes affecting multiple packages | All affected owners |
| Shared infrastructure | Changes to shared code | Platform team + affected owners |
| Build/config | Changes to build tooling or config | Platform team |
| Breaking change | Changes that alter public APIs | All affected owners + architecture review |
Results at scale
Teams running autter on monorepos with 100+ packages report:
| Metric | Before autter | After autter |
|---|---|---|
| Cross-package incidents per month | 4-7 | 0-1 |
| Avg review routing accuracy | ~60% | ~95% |
| Time to identify impact scope | 30-60 min (manual) | Under 2 min (automatic) |
| CI minutes per PR (avg) | 45 min | 12 min |
| Stale review requests | 30% of PRs | Under 5% of PRs |
The biggest win is the incidents you don't have. A shared utility change that breaks a downstream package in production is expensive — in debugging time, in incident response, in customer trust. autter catches these before merge, every time.
Getting started
# Initialise autter with monorepo mode
npx autter init --monorepo
# autter will detect your package manager (npm/pnpm/yarn workspaces,
# Turborepo, Nx, Lerna) and build the dependency graph automatically
# Preview impact analysis for your current branch
npx autter impact --diff main...HEADYour monorepo is a force multiplier for your team. autter makes sure it doesn't become a liability.
