Monorepo Setup with Turborepo
Microfrontends don't require a monorepo, but shared code and coordinated builds are easier with one.
Outcome
Set up a Turborepo monorepo with workspace configuration, task orchestration, and remote caching.
Why Monorepo + Microfrontends
| Benefit | How It Helps |
|---|---|
| Shared packages | One Header component, used everywhere |
| Atomic commits | Change shared code and all consumers together |
| Coordinated builds | Turborepo builds dependencies in the right order |
| Remote caching | Skip builds that haven't changed |
Vercel uses this pattern: all 12 microfrontend projects live in one monorepo with shared packages for headers, footers, and design systems.
Fast Track
- Create a new directory and initialize Turborepo
- Configure pnpm workspaces
- Verify the setup runs
Hands-on Exercise 1.3
Initialize the Acme Platform monorepo from scratch.
Requirements:
- Create a new directory called
acme-platform - Initialize with pnpm and Turborepo
- Configure workspaces for
apps/*andpackages/* - Set up the turbo.json task configuration
Step 1: Create the directory structure
mkdir acme-platform
cd acme-platformStep 2: Initialize package.json
Create package.json:
{
"name": "acme-platform",
"private": true,
"scripts": {
"dev": "turbo dev",
"build": "turbo build",
"lint": "turbo lint"
},
"devDependencies": {
"turbo": "^2.3.0"
},
"packageManager": "pnpm@9.15.0"
}Step 3: Configure pnpm workspaces
Create pnpm-workspace.yaml:
packages:
- "apps/*"
- "packages/*"Step 4: Configure Turborepo
Create turbo.json:
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": ["^lint"]
}
}
}Step 5: Create directory structure
mkdir -p apps packagesStep 6: Install dependencies
pnpm installTry It
After setup, your structure should look like:
acme-platform/
├── apps/ # Empty for now
├── packages/ # Empty for now
├── node_modules/
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
└── turbo.json
Verify Turborepo is working:
pnpm turbo --versionExpected output:
2.3.0
Understanding turbo.json
The configuration tells Turborepo how tasks relate:
{
"tasks": {
"build": {
"dependsOn": ["^build"], // Build dependencies first
"outputs": [".next/**", "!.next/cache/**"] // Cache these files
},
"dev": {
"cache": false, // Don't cache dev mode
"persistent": true // Keep running
}
}
}dependsOn: ["^build"]- The^means "build my dependencies before building me"outputs- Files Turborepo caches to skip future buildspersistent: true- The task keeps running (like a dev server)
Commit
git init
git add -A
git commit -m "chore: initialize turborepo monorepo"Done-When
acme-platformdirectory createdpackage.jsonwith turbo scripts configuredpnpm-workspace.yamlpointing to apps/* and packages/*turbo.jsonwith build, dev, and lint taskspnpm installcompletes without errors
Optional: Enable Remote Caching
Remote caching shares build artifacts across machines. Enable it with Vercel:
npx turbo login
npx turbo linkAfter linking, builds on CI will reuse cached artifacts from local development (and vice versa). This becomes valuable once you have multiple applications building.
What's Next
Skeleton's ready. Now you'll create the three Next.js apps and a shared UI package.
Was this helpful?