claudecodeguide.dev

Templates

Template: Monorepo

CLAUDE.md for Turborepo monorepos. Package boundaries enforced, workspace-aware, no spaghetti imports.

On this page (7 sections)

Prerequisites: Complete the Interactive Guide (steps 1-5) and read The CLAUDE.md Guide first. You need Claude Code installed and understand how CLAUDE.md works before customizing a template.

Monorepos fall apart when code starts bleeding across boundaries. apps/web importing directly from apps/docs, utilities duplicated in three places, nobody sure where a type actually lives. This template solves that.

Use it for monorepos managed with Turborepo and npm/pnpm workspaces. It assumes a standard apps/ + packages/ layout. If you use Nx instead of Turborepo, swap the build commands but keep the boundary rules.

Monorepo template enforcing boundaries
CLAUDE.md
# CLAUDE.md

## Project Overview

Turborepo monorepo with npm workspaces. Multiple apps sharing common packages.

apps/ web/ - Next.js frontend (App Router) docs/ - Documentation site packages/ ui/ - Shared React component library (@repo/ui) config/ - Shared ESLint, TypeScript, Tailwind configs (@repo/config) utils/ - Shared utility functions (@repo/utils) types/ - Shared TypeScript types (@repo/types) db/ - Database client and schema (@repo/db)


## Build Commands

```bash
turbo run build           # Build all packages and apps
turbo run dev             # Dev servers for all apps
turbo run lint            # Lint everything
turbo run test            # Test everything
turbo run build --filter=web  # Build only the web app
turbo run dev --filter=web    # Dev server for web only

To work on a specific package:

cd packages/ui && npm run test
cd apps/web && npm run dev

Package Boundaries (Critical)

These rules prevent spaghetti dependencies:

  1. Apps never import from other apps. apps/web must not import from apps/docs. Share code through a package in packages/ instead.
  2. Packages import only from other packages. @repo/ui can depend on @repo/utils but never on apps/web.
  3. All shared packages use the @repo/ prefix. Import as @repo/ui, @repo/utils, etc.
  4. No relative imports across workspace boundaries. Never use ../../packages/ui. Always use the package name: import { Button } from '@repo/ui'.
  5. New shared code goes into the right package. Types in @repo/types, utilities in @repo/utils, components in @repo/ui. When nothing fits, create a new package.

Naming Conventions

  • Package directories: lowercase kebab-case (ui, utils, config)
  • Package names in package.json: @repo/package-name
  • Exports: each package defines explicit exports in package.json exports field
  • Internal modules: use src/ directory inside each package

Adding a New Package

  1. Create directory under packages/
  2. Add package.json with "name": "@repo/package-name"
  3. Add tsconfig.json extending @repo/config/tsconfig.base.json
  4. Register in root turbo.json if it has custom pipeline tasks
  5. Run npm install from the root to link the workspace

Testing

Each package owns its tests. Run from the package root or via Turbo.

  • packages/ui - Vitest + React Testing Library
  • packages/utils - Vitest
  • packages/db - Vitest with test database
  • apps/web - Jest + React Testing Library + Playwright for E2E

Rule: test the package where the code lives. Do not test @repo/ui components from inside apps/web. Test them in packages/ui/src/__tests__/.

CI Notes

  • Use turbo run build --affected on PRs to build only changed packages
  • Cache is stored remotely via Vercel Remote Cache
  • Each package must build independently. No implicit dependency on build order.
  • Changesets for versioning: run npx changeset before merging cross-package changes

Code Style

  • TypeScript strict mode across all packages
  • Shared ESLint config in @repo/config. Do not override rules per-package.
  • Shared Tailwind config in @repo/config. Apps extend it, packages consume tokens.
  • Immutable patterns. Never mutate arguments or shared state.

Communication Style

When working in this repo, always specify which package or app you are modifying. Say "in packages/ui" or "in apps/web", not just file paths.


### How to Use

1. Copy the code block above into a `CLAUDE.md` file at the monorepo root
2. Update the workspace structure to match your actual `apps/` and `packages/` layout
3. Replace `@repo/` with your actual scope if you use a different npm org prefix
4. Add a `CLAUDE.md` inside each app for app-specific rules. Claude reads the nearest one, so per-app configs layer on top of the root.

New guides, when they ship

One email, roughly weekly. CLAUDE.md templates, workflows I actually use, and the cut-for-length stuff that does not make the public guides. One-click unsubscribe.

Or follow on Substack