Monorepos introduce the most challenging AI rules management scenario. A single repo might contain a React frontend, Fastify API, a shared component library, and infrastructure scripts — each with completely different conventions. Apply rules too broadly and the AI makes wrong suggestions in the wrong context. Apply them too narrowly and you miss consistency wins.
The Core Problem
In a monorepo with a root-level .cursorrules saying "Use React with Tailwind," when the AI is helping with the Node.js API package, it will still try to apply React and Tailwind patterns. The rules don't know where in the repo you are.
The three strategies below solve this at different scales.
Strategy 1: Root Rules with Explicit Package Sections (Small Monorepos)
For monorepos with 2–4 packages, a single rules file with clearly delimited sections works well:
markdown# Monorepo: MyApp(Turborepo) ## Workspace - Wide Conventions - TypeScript strict mode in all packages - pnpm as package manager(not npm or yarn) - Biome for linting and formatting - Import workspace packages by name: @myapp/ui, @myapp/db ## apps / web — Next.js 15 Frontend - App Router, Server Components by default - Tailwind CSS v4 for styling - TanStack Query for client - side data fetching - Never import from apps/api directly — use the shared API client ## apps / api — Fastify Node.js API - Fastify 4 with TypeScript - Zod for request / response validation(use fastify - type - provider - zod) - NO React, NO Tailwind — this is a Node.js service - Return errors as: { error: { code: string, message: string }, statusCode: number } ## packages / ui — Shared Component Library - React 18 + TypeScript - No Next.js - specific code(must work in any React app) - Named exports only — no default exports - Props documented with JSDoc ## packages / db — Database Layer - Drizzle ORM with PostgreSQL - All queries in db / queries / directory - Never import from apps/ — only from packages/ ``` --- ## Strategy 2: Per-Package Rules Files (Large Monorepos) For monorepos with 5+ packages, maintain a separate rules file in each package:
my - monorepo / ├── .cursorrules # Workspace - wide conventions only ├── apps / │ ├── web / │ │ └── .cursorrules # Frontend - specific rules │ └── api / │ └── .cursorrules # Backend - specific rules └── packages / ├── ui / │ └── .cursorrules # UI library rules └── db / └── .cursorrules # Database package rules ```
How each tool handles nested rules:
| Tool | How it resolves nested rules |
|---|---|
| Cursor | Walks up from the current file, applies innermost .cursorrules + root |
| Claude Code | Reads from project root by default; sub-directory CLAUDE.md files merged |
| GitHub Copilot | Root .github/copilot-instructions.md only — no nesting support |
| Windsurf | Root .windsurfrules only — no nesting support |
| Cline | Root .clinerules only — no nesting support |
| OpenAI Codex | Root AGENTS.md only — no nesting support |
| Google Antigravity | Root .agent/rules/rules.md only — no nesting support |
| Gemini CLI | Root GEMINI.md only — no nesting support |
Strategy 3: Shared Base + Package Extensions (Turborepo/Nx)
For teams using Turborepo or Nx, maintain a minimal shared base and let each package extend it:
Root .cursorrules:
markdown# Shared Conventions All packages follow these rules.See the package - specific.cursorrules for additional conventions. - TypeScript strict mode everywhere - Named exports only(no default exports) - Biome for linting: `pnpm biome check` - pnpm workspace — use workspace protocol for cross - package imports: "@myapp/ui": "workspace:*" - Build: `pnpm turbo build --filter=[package-name]` - Test: `pnpm turbo test --filter=[package-name]` ``` **Package-level `.cursorrules` (apps/web):** ```markdown # apps / web — Next.js Frontend (See root.cursorrules for workspace - wide conventions) - Next.js 15 App Router - Tailwind CSS v4 - Server Components by default ('use client' only when needed) - Shadcn / ui for primitives(never modify / components / ui directly) ``` --- ## Critical: Import Boundary Rules The most valuable monorepo-specific rules define import boundaries: ```markdown ## Import Boundaries - apps / packages can import from packages/ but NEVER from other apps/ - packages / ui can import from packages/config only - packages / db must not import from any app or other package - Use absolute workspace imports: @myapp/ui — never use relative cross-package paths ``` Without these rules, the AI will happily suggest `../../ apps / web / lib / utils` when there's a shared package it should use instead. --- ## Turborepo-Specific Tips ```markdown ## Build Commands(Turborepo) - Build specific package: pnpm turbo build--filter = web - Test with watch: pnpm turbo test--filter = web-- --watch - Type check all: pnpm turbo type - check - Always run commands from the monorepo root, not from package directories ## Package Manager - Use pnpm exclusively(not npm or yarn) - Add dependencies to specific packages: pnpm add react--filter = web - Add to root: pnpm add - w typescript ```