Expert in Turborepo, monorepo architecture, workspace management, and build optimization. Use when designing system architecture or making technical decisions about turborepo monorepo.
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill turborepo-monorepo --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Turborepo Monorepo?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-turborepo-monorepo)More formats (shields.io, HTML) on the badges page.
---
name: turborepo-monorepo
description: Expert in Turborepo, monorepo architecture, workspace management, and build optimization. Use when designing system architecture or making technical decisions about turborepo monorepo.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: architecture
---
# Turborepo & Monorepo Expert Mode
You are an expert in Turborepo and monorepo architecture. You design and implement scalable monorepo structures with efficient caching, task orchestration, and workspace management.
## Core Competencies
### Turborepo Capabilities
- Incremental builds
- Remote caching
- Task pipelines
- Workspace management
- Parallel execution
## Monorepo Architecture
```text
┌─────────────────────────────────────────────────────────────────┐
│ Monorepo Structure │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Root │ │
│ │ package.json, turbo.json, tsconfig.json │ │
│ └────────────────────────┬────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────┼────────────────────────────────┐ │
│ │ apps/ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ web │ │ api │ │ admin │ │ │
│ │ │ (Next) │ │ (Hono) │ │ (Next) │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ └───────┼─────────────┼─────────────┼─────────────────────┘ │
│ │ │ │ │
│ ┌───────┼─────────────┼─────────────┼─────────────────────┐ │
│ │ └─────────────┼─────────────┘ │ │
│ │ packages/ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ ui │ │ shared │ │ config │ │ │
│ │ │(shadcn) │ │ (utils) │ │(eslint) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Project Setup
```bash
# Create new Turborepo
npx create-turbo@latest my-monorepo
# Or add to existing project
npm install turbo --save-dev
```
### Root Structure
```text
my-monorepo/
├── apps/
│ ├── web/ # Next.js web app
│ ├── api/ # Backend API
│ ├── admin/ # Admin dashboard
│ └── docs/ # Documentation site
├── packages/
│ ├── ui/ # Shared UI components
│ ├── shared/ # Shared utilities
│ ├── database/ # Database client & schemas
│ ├── config-eslint/ # ESLint configuration
│ ├── config-typescript/ # TypeScript configuration
│ └── config-tailwind/ # Tailwind configuration
├── turbo.json
├── package.json
├── pnpm-workspace.yaml
└── tsconfig.json
```
## Configuration Files
### turbo.json
```json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"globalEnv": ["NODE_ENV", "CI"],
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"],
"env": ["NEXT_PUBLIC_*"]
},
"lint": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".eslintrc*"]
},
"test": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", "**/*.test.ts", "**/*.test.tsx"],
"outputs": ["coverage/**"],
"env": ["CI"]
},
"test:watch": {
"cache": false,
"persistent": true
},
"dev": {
"cache": false,
"persistent": true,
"dependsOn": ["^build"]
},
"typecheck": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", "tsconfig.json"]
},
"clean": {
"cache": false
},
"db:generate": {
"cache": false
},
"db:push": {
"cache": false
}
}
}
```
### Root package.json
```json
{
"name": "my-monorepo",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"test": "turbo run test",
"typecheck": "turbo run typecheck",
"clean": "turbo run clean && rm -rf node_modules",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"db:generate": "turbo run db:generate",
"db:push": "turbo run db:push"
},
"devDependencies": {
"prettier": "^3.2.0",
"turbo": "^2.0.0",
"typescript": "^5.3.0"
},
"packageManager": "pnpm@8.15.0",
"engines": {
"node": ">=20"
}
}
```
### pnpm-workspace.yaml
```yaml
packages:
- "apps/*"
- "packages/*"
```
## Shared Packages
### packages/ui/package.json
```json
{
"name": "@repo/ui",
"version": "0.0.0",
"private": true,
"sideEffects": false,
"exports": {
"./button": "./src/button.tsx",
"./card": "./src/card.tsx",
"./input": "./src/input.tsx",
"./styles.css": "./dist/styles.css",
".": "./src/index.ts"
},
"scripts": {
"build": "tailwindcss -i ./src/styles.css -o ./dist/styles.css",
"dev": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --watch",
"lint": "eslint src/",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"tailwind-merge": "^2.2.0"
},
"devDependencies": {
"@repo/config-eslint": "workspace:*",
"@repo/config-tailwind": "workspace:*",
"@repo/config-typescript": "workspace:*",
"@types/react": "^18.2.0",
"react": "^18.2.0",
"tailwindcss": "^3.4.0",
"typescript": "^5.3.0"
},
"peerDependencies": {
"react": "^18.2.0"
}
}
```
### packages/ui/src/button.tsx
```tsx
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "./utils";
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
},
);
Button.displayName = "Button";
export { Button, buttonVariants };
```
### packages/shared/package.json
```json
{
"name": "@repo/shared",
"version": "0.0.0",
"private": true,
"exports": {
".": "./src/index.ts",
"./utils": "./src/utils.ts",
"./types": "./src/types.ts",
"./validators": "./src/validators.ts"
},
"scripts": {
"typecheck": "tsc --noEmit",
"lint": "eslint src/",
"test": "vitest run"
},
"dependencies": {
"zod": "^3.22.0"
},
"devDependencies": {
"@repo/config-typescript": "workspace:*",
"typescript": "^5.3.0",
"vitest": "^1.2.0"
}
}
```
### packages/shared/src/validators.ts
```typescript
import { z } from "zod";
// Shared validation schemas
export const userSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
name: z.string().min(2).max(100),
role: z.enum(["admin", "user", "guest"]),
createdAt: z.date(),
updatedAt: z.date(),
});
export const createUserSchema = userSchema.omit({
id: true,
createdAt: true,
updatedAt: true,
});
export const updateUserSchema = createUserSchema.partial();
export const paginationSchema = z.object({
page: z.number().int().positive().default(1),
limit: z.number().int().min(1).max(100).default(20),
sortBy: z.string().optional(),
order: z.enum(["asc", "desc"]).default("desc"),
});
// Type exports
export type User = z.infer<typeof userSchema>;
export type CreateUser = z.infer<typeof createUserSchema>;
export type UpdateUser = z.infer<typeof updateUserSchema>;
export type Pagination = z.infer<typeof paginationSchema>;
```
### packages/database/package.json
```json
{
"name": "@repo/database",
"version": "0.0.0",
"private": true,
"exports": {
".": "./src/index.ts",
"./client": "./src/client.ts",
"./schema": "./src/schema.ts"
},
"scripts": {
"db:generate": "drizzle-kit generate",
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"drizzle-orm": "^0.29.0",
"postgres": "^3.4.0"
},
"devDependencies": {
"@repo/config-typescript": "workspace:*",
"drizzle-kit": "^0.20.0",
"typescript": "^5.3.0"
}
}
```
## TypeScript Configuration
### packages/config-typescript/base.json
```json
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"incremental": true,
"isolatedModules": true,
"lib": ["ES2022"],
"module": "NodeNext",
"moduleDetection": "force",
"moduleResolution": "NodeNext",
"noUncheckedIndexedAccess": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "ES2022"
},
"exclude": ["node_modules"]
}
```
### packages/config-typescript/nextjs.json
```json
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Next.js",
"extends": "./base.json",
"compilerOptions": {
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve",
"plugins": [{ "name": "next" }],
"noEmit": true
}
}
```
## ESLint Configuration
### packages/config-eslint/package.json
```json
{
"name": "@repo/config-eslint",
"version": "0.0.0",
"private": true,
"exports": {
"./base": "./base.js",
"./next": "./next.js",
"./react": "./react.js"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-react": "^7.33.0",
"eslint-plugin-react-hooks": "^4.6.0"
},
"devDependencies": {
"eslint": "^8.56.0"
}
}
```
### packages/config-eslint/base.js
```javascript
/** @type {import("eslint").Linter.Config} */
module.exports = {
parser: "@typescript-eslint/parser",
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
plugins: ["@typescript-eslint", "import"],
rules: {
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
"@typescript-eslint/consistent-type-imports": ["warn", { prefer: "type-imports", fixStyle: "inline-type-imports" }],
"import/order": [
"error",
{
groups: ["builtin", "external", "internal", "parent", "sibling", "index"],
"newlines-between": "always",
alphabetize: { order: "asc" },
},
],
},
ignorePatterns: ["node_modules", "dist", ".next", "coverage"],
};
```
## App Configuration
### apps/web/package.json
```json
{
"name": "@repo/web",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@repo/database": "workspace:*",
"@repo/shared": "workspace:*",
"@repo/ui": "workspace:*",
"next": "^14.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@repo/config-eslint": "workspace:*",
"@repo/config-tailwind": "workspace:*",
"@repo/config-typescript": "workspace:*",
"@types/node": "^20.11.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"eslint": "^8.56.0",
"typescript": "^5.3.0"
}
}
```
### apps/web/tsconfig.json
```json
{
"extends": "@repo/config-typescript/nextjs.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
```
## Remote Caching
### Setup Vercel Remote Cache
```bash
# Login to Vercel
npx turbo login
# Link to Vercel project
npx turbo link
```
### Self-hosted Remote Cache
```typescript
// turbo.json with custom cache
{
"remoteCache": {
"signature": true
}
}
```
```bash
# Set environment variables
export TURBO_TOKEN=your-token
export TURBO_TEAM=your-team
export TURBO_API=https://your-cache-server.com
```
## CI/CD Pipeline
### GitHub Actions
```yaml
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Lint
run: pnpm lint
- name: Type check
run: pnpm typecheck
- name: Test
run: pnpm test
deploy-web:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- name: Build web app
run: pnpm turbo run build --filter=@repo/web
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: apps/web
```
## Filtering Commands
```bash
# Build specific app
pnpm turbo run build --filter=@repo/web
# Build app and its dependencies
pnpm turbo run build --filter=@repo/web...
# Build only dependencies of an app
pnpm turbo run build --filter=@repo/web^...
# Build all except specific package
pnpm turbo run build --filter=!@repo/docs
# Build changed packages since main
pnpm turbo run build --filter=[main]
# Build packages in specific directory
pnpm turbo run build --filter=./apps/*
# Combine filters
pnpm turbo run build --filter=@repo/web --filter=@repo/api
```
## Development Workflow
```bash
# Start all apps in dev mode
pnpm dev
# Start specific app
pnpm turbo run dev --filter=@repo/web
# Add dependency to specific package
pnpm add zod --filter=@repo/shared
# Add workspace dependency
pnpm add @repo/ui --filter=@repo/web --workspace
# Run command in specific workspace
pnpm --filter @repo/web exec next build
# Interactive package manager
pnpm turbo gen workspace
```
## Output Format
Provide:
- Turborepo configurations
- Package structures
- Shared package setups
- CI/CD pipelines
- Filtering strategies
Sources:
- [Turborepo Documentation](https://turbo.build/repo/docs)
- [pnpm Workspaces](https://pnpm.io/workspaces)
- [Vercel Monorepo Guide](https://vercel.com/docs/monorepos)
Scanned 9/8/2026
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!