engineering

Monorepo Setup Guide

Scaffold and configure monorepos using Turborepo or Nx. Covers workspace structure, package organization, build caching, task pipelines, dependency management, and incremental adoption strategies.

monorepoturboreponxworkspacebuild-cachetask-pipelinepnpm

Works well with agents

Developer Experience Engineer AgentMonorepo Architect AgentPlatform Engineer Agent

Works well with skills

Architecture Decision RecordCI/CD Pipeline Design
$ npx skills add The-AI-Directory-Company/(…) --skill monorepo-setup-guide
monorepo-setup-guide/
    • pnpm-workspace.yaml209 B
    • tsconfig.base.json905 B
    • turbo.json1.1 KB
    • greenfield-nextjs-api.md10.0 KB
    • turborepo-vs-nx.md7.7 KB
  • SKILL.md6.7 KB
SKILL.md
Markdown
1 
2# Monorepo Setup Guide
3 
4## Before you start
5 
6Gather the following from the user:
7 
81. **Which tool?** (Turborepo, Nx, or help deciding)
92. **What packages will exist?** (Apps, shared libraries, configs)
103. **Package manager?** (pnpm, npm, yarn — pnpm recommended for monorepos)
114. **What language/framework?** (TypeScript, React, Next.js, Node.js, mixed)
125. **Existing repo or greenfield?** (Migrating from multi-repo or starting fresh)
136. **Team size?** (Affects caching and CI strategy)
14 
15If the user says "set up a monorepo," push back: "What packages do you need? I need to know the apps, shared libraries, and your package manager to design the workspace structure."
16 
17**Turborepo vs Nx decision guide:**
18- Turborepo: Simpler mental model, zero-config caching, good for TypeScript/JS monorepos under 20 packages.
19- Nx: More features (generators, affected commands, module boundary rules), better for large monorepos (20+ packages) or polyglot stacks.
20 
21## Procedure
22 
23### Step 1: Define the workspace structure
24 
25```
26monorepo/
27 apps/
28 web/ # Next.js frontend
29 api/ # Express/Fastify backend
30 mobile/ # React Native app
31 packages/
32 ui/ # Shared component library
33 config-eslint/ # Shared ESLint config
34 config-typescript/ # Shared tsconfig
35 shared-utils/ # Shared utility functions
36 database/ # Database client and schema
37 tooling/
38 scripts/ # Build and maintenance scripts
39 turbo.json # or nx.json
40 package.json # Root workspace config
41 pnpm-workspace.yaml # Workspace package globs
42```
43 
44Rules for package organization:
45- `apps/` contains deployable applications. Each has its own build output.
46- `packages/` contains shared libraries consumed by apps or other packages.
47- Config packages (`config-*`) export shared tool configurations.
48- Every package has its own `package.json` with a `name` field using a scope: `@repo/ui`.
49 
50### Step 2: Configure the workspace root
51 
52Create `pnpm-workspace.yaml` listing `apps/*`, `packages/*`, and `tooling/*`. Root `package.json` should be `private: true`, define scripts that delegate to turbo (`turbo build`, `turbo dev`, etc.), pin `packageManager` version, and install only workspace-level tools (turbo) as devDependencies. All other dependencies go in the package that uses them.
53 
54### Step 3: Configure the task pipeline
55 
56Define tasks in `turbo.json` (or `nx.json` with `targetDefaults`). Essential task definitions:
57 
58- **build:** `dependsOn: ["^build"]`, `outputs: ["dist/**", ".next/**"]`
59- **dev:** `cache: false`, `persistent: true`
60- **lint:** `dependsOn: ["^build"]`
61- **test:** `dependsOn: ["build"]`
62- **clean:** `cache: false`
63 
64Key pipeline concepts:
65- `^build` means "run build in my dependencies first" (topological dependency)
66- `dependsOn: ["build"]` means "run my own build first"
67- `outputs` defines what gets cached — must include all build artifacts
68- `cache: false` for dev servers and clean commands
69- `persistent: true` for long-running dev servers
70 
71### Step 4: Set up internal package references
72 
73Each package that depends on another workspace package:
74 
75Each shared package needs a scoped `name` (`@repo/ui`), `main`, `types`, and `exports` fields pointing to source entry points. Consumer packages reference them with `"@repo/ui": "workspace:*"` in dependencies. The `workspace:*` protocol tells the package manager to resolve from the workspace, not the registry.
76 
77### Step 5: Configure shared TypeScript
78 
79Create a `packages/config-typescript/base.json` with strict settings: `strict: true`, `target: ES2022`, `module: ESNext`, `moduleResolution: bundler`, `declaration: true`, `isolatedModules: true`. Each package extends it with `"extends": "@repo/config-typescript/base.json"` and adds its own `outDir` and `include` paths. Different packages override as needed (React packages add `jsx`, Node packages adjust `module`).
80 
81### Step 6: Enable remote caching
82 
83**Turborepo:** `npx turbo login && npx turbo link` to connect Vercel Remote Cache. **Nx:** `npx nx connect` for Nx Cloud. Both support self-hosted alternatives. Remote caching shares build artifacts across developers and CI — expected impact is 40-70% CI time reduction after warm cache.
84 
85### Step 7: Configure CI for monorepos
86 
87Use filtering to only build/test affected packages. Turborepo: `turbo build --filter=...[origin/main]`. Nx: `nx affected --target=build --base=origin/main`. CI pipeline should restore remote cache, run affected commands, and only deploy apps whose build output changed.
88 
89## Quality checklist
90 
91Before delivering the monorepo setup, verify:
92 
93- [ ] Every package has a scoped `name` in its package.json
94- [ ] `pnpm-workspace.yaml` (or equivalent) lists all package directories
95- [ ] Task pipeline defines `dependsOn` with correct topological order
96- [ ] Build `outputs` are specified so caching works correctly
97- [ ] Internal packages use `workspace:*` protocol for references
98- [ ] TypeScript configs extend a shared base config
99- [ ] Dev command is marked `cache: false` and `persistent: true`
100- [ ] CI uses affected/filter commands, not full rebuild
101 
102## Common mistakes
103 
104- **Missing `outputs` in task config.** If `outputs` is empty or wrong, the cache stores nothing. Builds re-run every time despite "cache hit" messages.
105- **Circular dependencies between packages.** Package A imports from B, B imports from A. This breaks topological builds. Refactor shared code into a third package.
106- **Installing dependencies at the root.** Putting `react` in the root `package.json` makes all packages implicitly depend on it. Install dependencies in the package that uses them.
107- **Not using `workspace:*` protocol.** Referencing internal packages by version (`"@repo/ui": "^1.0.0"`) causes the package manager to look in the registry instead of the workspace.
108- **Skipping remote cache setup.** Without remote caching, every CI run and every developer rebuilds from scratch. This is the single biggest monorepo performance win.
109- **One tsconfig for everything.** Different packages need different settings (React needs JSX, Node packages do not). Use a shared base config that each package extends with overrides.
110 

©2026 ai-directory.company

·Privacy·Terms·Cookies·