Complex Project Architecture with AI
Monorepo Patterns with AI Assistance
5 min read
Why Monorepos for AI-Assisted Development?
Monorepos provide AI assistants with crucial advantages:
- Complete Context: AI can see all packages and their relationships
- Consistent Patterns: Shared configs mean consistent code style
- Type Safety: Shared types across packages
- Atomic Changes: Modify multiple packages in one commit
Monorepo Structure for AI
Optimal Directory Layout
my-monorepo/
├── apps/
│ ├── web/ # Next.js frontend
│ ├── api/ # Node.js backend
│ └── admin/ # Admin dashboard
├── packages/
│ ├── ui/ # Shared React components
│ ├── database/ # Prisma schema & client
│ ├── types/ # Shared TypeScript types
│ ├── utils/ # Shared utilities
│ └── config/ # Shared configs (ESLint, TS)
├── turbo.json
├── package.json
└── .claude/
└── context.md # AI context documentation
AI Context File
Create a context file that helps AI understand your monorepo:
<!-- .claude/context.md -->
# Monorepo Context
## Package Relationships
- `apps/web` depends on: `packages/ui`, `packages/types`, `packages/utils`
- `apps/api` depends on: `packages/database`, `packages/types`, `packages/utils`
- `packages/ui` depends on: `packages/types`
- `packages/database` depends on: `packages/types`
## Development Commands
- `pnpm dev` - Start all apps
- `pnpm build` - Build all packages
- `pnpm test` - Run all tests
- `turbo run build --filter=web` - Build specific app
## Adding New Components
1. Shared components go in `packages/ui`
2. App-specific components go in `apps/[app]/components`
3. All components must export from index.ts
## Type Conventions
- API response types in `packages/types/api.ts`
- Database models in `packages/types/models.ts`
- Shared utilities in `packages/types/utils.ts`
AI-Assisted Package Creation
Creating a New Shared Package
claude "Create a new shared package 'packages/email' for
sending transactional emails. Include:
1. Package setup with proper tsconfig
2. Email service abstraction
3. SendGrid and Resend providers
4. Type definitions
5. Export configuration"
Claude Code generates the complete package:
// packages/email/src/index.ts
export { EmailService } from './service';
export { SendGridProvider } from './providers/sendgrid';
export { ResendProvider } from './providers/resend';
export type { EmailProvider, EmailOptions, EmailResult } from './types';
// packages/email/src/types.ts
export interface EmailOptions {
to: string | string[];
subject: string;
html: string;
text?: string;
from?: string;
replyTo?: string;
}
export interface EmailResult {
success: boolean;
messageId?: string;
error?: string;
}
export interface EmailProvider {
send(options: EmailOptions): Promise<EmailResult>;
}
// packages/email/src/service.ts
import type { EmailProvider, EmailOptions, EmailResult } from './types';
export class EmailService {
constructor(private provider: EmailProvider) {}
async send(options: EmailOptions): Promise<EmailResult> {
return this.provider.send(options);
}
async sendBatch(emails: EmailOptions[]): Promise<EmailResult[]> {
return Promise.all(emails.map((email) => this.send(email)));
}
}
Wiring Up Dependencies
claude "Add the email package as a dependency to apps/api.
Update the dependency graph in turbo.json if needed."
Cross-Package Refactoring
Scenario: Renaming a Shared Type
claude "Rename the 'User' type to 'UserProfile' across
the entire monorepo. Update:
1. packages/types/models.ts (definition)
2. All imports in apps/web
3. All imports in apps/api
4. All imports in packages/ui
Ensure no breaking changes."
Claude Code performs atomic refactoring:
## Refactoring Summary
Files modified: 24
- packages/types/src/models.ts (definition renamed)
- apps/web/src/components/UserCard.tsx
- apps/web/src/hooks/useUser.ts
- apps/api/src/routes/users.ts
- apps/api/src/services/auth.ts
- packages/ui/src/components/Avatar.tsx
... (18 more files)
All TypeScript compilation checks pass.
All tests pass.
Turborepo-Specific Patterns
Configuring Pipeline for AI
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"test": {
"dependsOn": ["build"],
"outputs": []
},
"lint": {
"outputs": []
},
"typecheck": {
"dependsOn": ["^build"],
"outputs": []
}
}
}
AI-Assisted Build Debugging
claude "Our Turbo build is failing with circular dependency
errors. Analyze the dependency graph and fix the issue."
Claude Code investigates:
## Build Analysis
Found circular dependency:
packages/utils → packages/types → packages/utils
Chain:
1. packages/utils imports formatDate from packages/types
2. packages/types imports ValidationError from packages/utils
Solution:
Move ValidationError to packages/types/errors.ts
Update imports in packages/utils to use packages/types
Executing fix...
Nx-Specific Patterns
Using Nx Generators with AI
claude "Use Nx to generate a new React library for charts.
Configure it with our existing Tailwind and testing setup."
# AI executes
npx nx generate @nx/react:library charts \
--directory=packages/charts \
--style=tailwind \
--unitTestRunner=vitest \
--bundler=vite
Affected Analysis
claude "What packages will be affected if I modify
packages/database/schema.prisma?"
# AI runs
npx nx affected:graph --base=main
# Returns
Affected projects:
- packages/database (modified)
- packages/types (depends on database)
- apps/api (depends on database)
- apps/web (depends on types)
- apps/admin (depends on types, database)
Workspace-Wide Operations
Bulk Updates
claude "Update all packages to use the new logger from
packages/utils/logger instead of console.log. Apply to:
- All apps
- All packages except utils itself
Follow existing import patterns."
Dependency Synchronization
claude "Ensure all packages use the same version of React.
Check for version mismatches and update package.json files."
Best Practices for Monorepo AI Development
- Keep Context Files Updated: Maintain
.claude/context.md - Use Workspace Protocols:
"workspace:*"for internal deps - Consistent Tooling: Same testing, linting across packages
- Explicit Boundaries: Clear package responsibilities
- Automated Checks: CI validates cross-package changes
Module Summary
You've learned how to:
- Make AI-driven architectural decisions
- Build full-stack features with coordinated AI
- Manage monorepo complexity with AI assistance
Next, we'll tackle large codebase management—working with AI on codebases with hundreds of thousands of lines. :::