Skip to content
Back to skills

Turborepo Monorepo

BSecurity

Expert in Turborepo, monorepo architecture, workspace management, and build optimization. Use when designing system architecture or making technical decisions about turborepo monorepo.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
developmentjavascripttypescriptgojavabashreactnextjsnodegitapi

Works with

  • cli
  • api

Security analysis

B85/100
  • highPerforms destructive filesystem operations
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill turborepo-monorepo --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Turborepo Monorepo?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Turborepo Monorepo
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-turborepo-monorepo/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-turborepo-monorepo)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.