CODITECT Production Folder Standard - Monorepo Projects
Version: 1.0.0 Last Updated: 2025-12-04 Applies To: Nx, Turborepo, Lerna, pnpm workspaces, Yarn workspaces Status: Production Standard
Overview
This standard defines the production-ready folder structure for monorepo projects containing multiple applications and shared libraries. Common for full-stack projects, microservices, and multi-platform applications.
Key Principles:
- Application isolation - Each app is independent
- Shared code extraction - Common code in packages/libs
- Tool-agnostic - Works with Nx, Turborepo, Lerna
- Dependency management - Clear boundaries between apps and libs
- Build optimization - Parallel builds, caching, affected detection
Required Root Directory Structure
✅ Must Have in Root
monorepo-root/
├── README.md # Monorepo documentation
├── CLAUDE.md # AI agent context
├── CONTRIBUTING.md # Contribution guidelines
├── CHANGELOG.md # Version history
├── LICENSE # License file
├── SECURITY.md # Security policy
├── package.json # Root workspace config
├── pnpm-workspace.yaml # pnpm workspaces
├── nx.json # Nx configuration
├── turbo.json # Turborepo configuration
├── lerna.json # Lerna configuration
├── tsconfig.base.json # Base TypeScript config
├── .gitignore # Git ignore rules
├── .eslintrc.json # Root linting config
├── .prettierrc # Code formatting
└── docker-compose.yml # Local development
❌ Must NOT Have in Root
❌ Application code (*.tsx, *.py, *.rs)
❌ Shared library code directly in root
❌ Build artifacts
❌ Test files
❌ node_modules/ (should be in root only for hoisting)
Monorepo Structure Options
Option 1: Nx Monorepo (Enterprise)
monorepo/
├── apps/ # Applications
│ ├── web/ # Frontend web app (Next.js)
│ │ ├── src/
│ │ ├── public/
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── project.json # Nx project config
│ │ └── README.md
│ ├── mobile/ # Mobile app (React Native)
│ │ ├── src/
│ │ ├── android/
│ │ ├── ios/
│ │ ├── package.json
│ │ └── project.json
│ ├── api/ # Backend API (Node.js/FastAPI)
│ │ ├── src/
│ │ ├── package.json
│ │ ├── Dockerfile
│ │ └── project.json
│ ├── admin/ # Admin dashboard
│ │ ├── src/
│ │ ├── package.json
│ │ └── project.json
│ └── worker/ # Background worker
│ ├── src/
│ ├── package.json
│ └── project.json
│
├── libs/ # Shared libraries
│ ├── frontend/
│ │ ├── ui/ # Shared UI components
│ │ │ ├── src/
│ │ │ │ ├── Button/
│ │ │ │ ├── Card/
│ │ │ │ └── index.ts
│ │ │ ├── package.json
│ │ │ └── project.json
│ │ ├── state/ # State management
│ │ │ ├── src/
│ │ │ ├── package.json
│ │ │ └── project.json
│ │ └── hooks/ # Shared hooks
│ │ ├── src/
│ │ ├── package.json
│ │ └── project.json
│ ├── backend/
│ │ ├── auth/ # Authentication logic
│ │ │ ├── src/
│ │ │ ├── package.json
│ │ │ └── project.json
│ │ ├── database/ # Database utilities
│ │ │ ├── src/
│ │ │ ├── package.json
│ │ │ └── project.json
│ │ └── email/ # Email service
│ │ ├── src/
│ │ ├── package.json
│ │ └── project.json
│ └── shared/
│ ├── types/ # Shared TypeScript types
│ │ ├── src/
│ │ │ ├── user.ts
│ │ │ ├── post.ts
│ │ │ └── index.ts
│ │ ├── package.json
│ │ └── project.json
│ ├── utils/ # Shared utilities
│ │ ├── src/
│ │ ├── package.json
│ │ └── project.json
│ ├── config/ # Shared configuration
│ │ ├── src/
│ │ ├── package.json
│ │ └── project.json
│ └── constants/ # Shared constants
│ ├── src/
│ ├── package.json
│ └── project.json
│
├── tools/ # Development tools
│ ├── generators/ # Code generators
│ │ ├── app/
│ │ └── lib/
│ ├── scripts/ # Utility scripts
│ │ ├── build-all.sh
│ │ ├── test-all.sh
│ │ └── deploy.sh
│ └── webpack-plugins/ # Custom webpack plugins
│
├── docs/ # Documentation
│ ├── api/
│ ├── architecture/
│ │ └── adrs/
│ ├── deployment/
│ └── monorepo-guide.md
│
├── dist/ # Build output (gitignored)
│ ├── apps/
│ └── libs/
│
└── node_modules/ # Hoisted dependencies
Option 2: Turborepo (Simpler)
monorepo/
├── apps/ # Applications
│ ├── web/ # Next.js frontend
│ │ ├── app/
│ │ ├── public/
│ │ ├── package.json
│ │ └── turbo.json
│ ├── docs/ # Documentation site
│ │ ├── pages/
│ │ ├── public/
│ │ └── package.json
│ └── api/ # Express backend
│ ├── src/
│ ├── package.json
│ └── Dockerfile
│
├── packages/ # Shared packages
│ ├── ui/ # UI component library
│ │ ├── src/
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── config/ # Shared configs
│ │ ├── eslint/
│ │ ├── typescript/
│ │ └── package.json
│ ├── tsconfig/ # TypeScript configs
│ │ ├── base.json
│ │ ├── nextjs.json
│ │ └── package.json
│ └── types/ # Shared types
│ ├── src/
│ └── package.json
│
├── package.json # Root workspace
├── turbo.json # Turborepo config
└── pnpm-workspace.yaml # pnpm workspaces
Option 3: Simple Monorepo (Minimal)
monorepo/
├── src/
│ ├── client/ # Frontend (React)
│ │ ├── components/
│ │ ├── pages/
│ │ └── package.json
│ └── server/ # Backend (Node.js)
│ ├── routes/
│ ├── controllers/
│ └── package.json
│
├── shared/ # Shared code
│ ├── types/
│ └── utils/
│
├── docs/
├── scripts/
└── package.json # Root workspace
Workspace Configuration
pnpm Workspaces
# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'libs/*'
- 'packages/*'
- 'tools/*'
Nx Configuration
// nx.json
{
"npmScope": "@myorg",
"affected": {
"defaultBase": "main"
},
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "test", "lint"]
}
}
},
"targetDefaults": {
"build": {
"dependsOn": ["^build"]
}
}
}
Turborepo Configuration
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"test": {
"dependsOn": ["build"],
"cache": false
},
"lint": {
"outputs": []
},
"dev": {
"cache": false,
"persistent": true
}
}
}
Documentation Organization
docs/
├── architecture/ # Architecture documentation
│ ├── adrs/ # Monorepo-specific ADRs
│ │ ├── ADR-001-monorepo-tool.md
│ │ ├── ADR-002-shared-types.md
│ │ └── ADR-003-dependency-management.md
│ ├── C4-monorepo-context.md
│ └── inter-app-communication.md
├── deployment/ # Deployment guides
│ ├── docker-monorepo.md
│ ├── kubernetes-multi-app.md
│ └── ci-cd-monorepo.md
├── project-management/
│ ├── PROJECT-PLAN.md
│ └── TASKLIST-WITH-CHECKBOXES.md
├── apps/ # App-specific docs
│ ├── web/
│ │ └── README.md
│ └── api/
│ └── README.md
└── packages/ # Package-specific docs
├── ui/
│ └── README.md
└── types/
└── README.md
Scripts Organization
scripts/ # Monorepo scripts
├── build/
│ ├── build-all.sh # Build all apps
│ ├── build-affected.sh # Build affected apps only
│ └── build-app.sh # Build specific app
├── test/
│ ├── test-all.sh # Test all apps
│ ├── test-affected.sh # Test affected apps only
│ └── test-app.sh # Test specific app
├── deploy/
│ ├── deploy-all.sh # Deploy all apps
│ ├── deploy-app.sh # Deploy specific app
│ └── rollback.sh # Rollback deployment
├── dev/
│ ├── start-all.sh # Start all dev servers
│ └── start-app.sh # Start specific app
└── utils/
├── sync-versions.sh # Sync package versions
├── check-deps.sh # Check for circular deps
└── generate-types.sh # Generate shared types
Dependency Management
Internal Dependencies
// apps/web/package.json
{
"name": "@myorg/web",
"dependencies": {
"@myorg/ui": "workspace:*",
"@myorg/types": "workspace:*",
"@myorg/utils": "workspace:*"
}
}
// libs/ui/package.json
{
"name": "@myorg/ui",
"dependencies": {
"@myorg/types": "workspace:*"
}
}
Versioning Strategy
// package.json (root)
{
"version": "1.0.0",
"workspaces": [
"apps/*",
"libs/*",
"packages/*"
]
}
Build Output Organization
dist/ # Build artifacts (gitignored)
├── apps/
│ ├── web/
│ │ ├── .next/
│ │ └── out/
│ ├── api/
│ │ └── bundle.js
│ └── mobile/
│ ├── android/
│ └── ios/
└── libs/
├── ui/
│ └── dist/
└── types/
└── dist/
CI/CD for Monorepo
GitHub Actions Example
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all history for affected detection
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Install dependencies
run: pnpm install
- name: Build affected
run: pnpm nx affected --target=build --base=origin/main
- name: Test affected
run: pnpm nx affected --target=test --base=origin/main
- name: Lint affected
run: pnpm nx affected --target=lint --base=origin/main
Project Type Detection Rules
Detect as Monorepo if:
- Has
apps/andlibs/orpackages/directories - Has workspace configuration (pnpm-workspace.yaml, lerna.json, nx.json, turbo.json)
- Root package.json has
workspacesfield - Multiple package.json files in subdirectories
Tool Detection:
- Nx: Has
nx.jsonor@nrwl/packages - Turborepo: Has
turbo.json - Lerna: Has
lerna.json - pnpm: Has
pnpm-workspace.yaml - Yarn: Has
"workspaces"in package.json
Production Readiness Checklist
Root Configuration (25 points)
- 5 pts: Workspace configuration present (pnpm-workspace.yaml, nx.json, turbo.json)
- 5 pts: Root documentation (README, CLAUDE, CONTRIBUTING)
- 5 pts: Shared configuration (tsconfig.base.json, .eslintrc)
- 5 pts: CI/CD configuration for monorepo
- 5 pts: Comprehensive .gitignore
Application Organization (25 points)
- 5 pts: Clear apps/ directory with independent applications
- 5 pts: Each app follows respective standard (frontend/backend)
- 5 pts: No circular dependencies between apps
- 5 pts: App-specific configuration and documentation
- 5 pts: Independent deployment capability
Shared Code Organization (25 points)
- 5 pts: Clear libs/ or packages/ directory
- 5 pts: Proper namespace (@myorg/package-name)
- 5 pts: Shared types extracted to common package
- 5 pts: No circular dependencies between libs
- 5 pts: Each lib has clear purpose and README
Build & Deployment (25 points)
- 5 pts: Build caching configured (Nx/Turborepo)
- 5 pts: Affected-only builds working
- 5 pts: Scripts for monorepo operations
- 5 pts: Docker configuration for each app
- 5 pts: CI/CD pipeline optimized for monorepo
Total Score: 100 points Production Ready: 90+ points Needs Improvement: 70-89 points Not Ready: <70 points
Common Anti-Patterns to Avoid
❌ Don't Do This
❌ Circular dependencies between apps/libs
❌ Shared code directly in apps without extraction
❌ No versioning strategy for shared packages
❌ Building entire monorepo on every change
❌ No dependency boundaries enforcement
❌ Mixing app code with shared library code
❌ No caching or build optimization
✅ Do This Instead
✅ Clear dependency graph with no cycles
✅ Extract shared code to libs/ directory
✅ Use workspace protocol for internal deps
✅ Affected-only builds (Nx affected, Turbo cache)
✅ Enforce module boundaries with linting
✅ Keep apps and libs separate
✅ Configure build caching and parallelization
Monorepo Tool Comparison
| Feature | Nx | Turborepo | Lerna | pnpm Workspaces |
|---|---|---|---|---|
| Build Caching | ✅ Advanced | ✅ Advanced | ❌ No | ❌ No |
| Affected Detection | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
| Task Orchestration | ✅ Complex | ✅ Simple | ❌ Basic | ❌ No |
| Code Generation | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Learning Curve | High | Low | Medium | Low |
| Best For | Enterprise | Vercel stack | Legacy | Simple monorepos |
Migration Guide
Converting to monorepo:
- Choose tool - Nx for complex, Turborepo for simple
- Create structure - apps/ and libs/ directories
- Extract shared code - Identify common code
- Setup workspaces - Configure package manager
- Configure builds - Setup caching and affected detection
- Update CI/CD - Optimize for monorepo
- Document structure - Update README and docs
Use: /organize-production command with monorepo detection
References
Status: Production Standard ✅ Version: 1.0.0 Last Updated: 2025-12-04 Applies To: Nx, Turborepo, Lerna, pnpm workspaces, Yarn workspaces