Monorepo with Turborepo
Workspace setup, turborepo pipeline, shared packages, caching, CI integration.
monorepoturborepotoolingdevops
# Monorepo with Turborepo
## Create
```bash
npx create-turbo@latest my-monorepo
```
## Structure
```
my-monorepo/
apps/
web/ # Next.js app
docs/ # Docusaurus
api/ # Express API
packages/
ui/ # shared React components
config/ # shared ESLint, TS configs
utils/ # shared utilities
package.json # root (workspaces)
turbo.json
pnpm-workspace.yaml
```
## pnpm-workspace.yaml
```yaml
packages:
- 'apps/*'
- 'packages/*'
```
## turbo.json
```json
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"dev": {
"persistent": true,
"cache": false
},
"lint": {},
"test": { "outputs": ["coverage/**"] }
}
}
```
## Commands
```bash
# Run build in all packages (respects dependency order)
pnpm turbo build
# Run only for specific app
pnpm turbo build --filter=web
# Run dev for web + its dependencies
pnpm turbo dev --filter=web...
# Install package in specific workspace
pnpm add react --filter=ui
pnpm add @repo/ui --filter=web
```
## Shared UI package
```ts
// packages/ui/src/Button.tsx
export function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>
}
// packages/ui/package.json
{
"name": "@repo/ui",
"exports": { ".": "./src/index.tsx" },
"main": "./src/index.tsx"
}
// apps/web imports:
import { Button } from '@repo/ui'
```
## Shared TS config
```json
// packages/config/tsconfig/base.json
{
"compilerOptions": { "strict": true, "esModuleInterop": true }
}
// apps/web/tsconfig.json
{ "extends": "@repo/config/tsconfig/base.json" }
```
## Caching
- Turborepo caches task outputs by input hash.
- Remote cache (Vercel): `npx turbo login && npx turbo link`
- CI: set `TURBO_TOKEN` + `TURBO_TEAM` env vars.API: /api/skills/monorepo-turborepo