| name | monorepo-patterns |
| description | Structure and operate a monorepo — Turborepo or Nx workspace setup, shared packages, task pipeline caching, change detection, publishable vs internal packages, versioning strategy, and CI optimization. Use when asked about "monorepo", "Turborepo", "Nx", "workspace", "shared packages", "internal packages", "turbo.json", "task pipeline", "remote cache", "affected packages", "package dependency graph", "pnpm workspaces", "yarn workspaces", or "how to share code between apps". Do NOT use for: CI/CD pipeline wiring — see cicd-patterns. Do NOT use for: npm package publishing — see api-design for versioning principles.
|
| origin | yamtam-original |
| license | MIT © 2026 Vũ Văn Tâm |
| version | 1.0.0 |
| compatibility | Turborepo v2, Nx v18, pnpm v9. Node.js monorepo. framework-agnostic. |
When to Use
- Use when: sharing code between multiple apps (web, mobile, API, docs)
- Use when: build times are slow because everything rebuilds on every change
- Use when: inconsistent versions of shared components across services
- Do NOT use for: single-app projects — monorepo adds overhead
- Do NOT use for: microservices in different languages — use polyglot repo
Workspace Structure
monorepo/
├── apps/
│ ├── web/ ← Next.js consumer app
│ ├── api/ ← Express API
│ └── docs/ ← Documentation site
├── packages/
│ ├── ui/ ← React component library (publishable)
│ ├── config/ ← Shared ESLint/TS/Tailwind config (internal)
│ ├── utils/ ← Shared utilities (publishable or internal)
│ └── types/ ← Shared TypeScript types (internal)
├── turbo.json ← Turborepo task pipeline
├── pnpm-workspace.yaml ← Workspace definition
└── package.json ← Root scripts
pnpm Workspace Setup
packages:
- 'apps/*'
- 'packages/*'
{
"name": "@myorg/ui",
"version": "0.1.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --watch"
}
}
{
"dependencies": {
"@myorg/ui": "workspace:*"
}
}
Turborepo Pipeline (turbo.json)
{
"$schema": "https://turbo.build/schema.json",
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"],
"cache": true
},
"test": {
"dependsOn": ["^build"],
"inputs": ["src/**", "test/**"],
"outputs": ["coverage/**"]
turbo build
turbo build --filter=...[HEAD~1]
turbo build --filter=@myorg/web...
turbo login && turbo link
Shared Config Package
module.exports = {
extends: ['eslint:recommended', '@typescript-eslint/recommended'],
rules: {
'no-console': 'warn',
'@typescript-eslint/no-explicit-any': 'error',
},
};
module.exports = { extends: ['@myorg/config/eslint'] };
{
"compilerOptions": {
"strict": true,
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true
}
}
{
"extends": "@myorg/config/typescript/base.json",
"compilerOptions": { "plugins": [{ "name": "next" }] }
}
Versioning Strategy
| Package type | Strategy |
|---|
| Internal only | No versioning — workspace:* always |
| Publishable (npm) | Changesets — npx changeset per PR, changeset version before release |
| Apps (deployable) | Git SHA tag — versions irrelevant, deploy by SHA |
npx changeset
npx changeset version
npx changeset publish
Anti-Fake-Pass Rules
Before claiming monorepo setup is done, you MUST show:
Reference: gates/anti-fake-pass-gate.md