Turbo Monorepo Samples

Turbo monorepo build system examples including workspace configuration, task orchestration, and caching strategies

Key Facts

Category
Build Tools
Items
3
Format Families
json, yaml

Sample Overview

Turbo monorepo build system examples including workspace configuration, task orchestration, and caching strategies This sample set belongs to Build Tools and can be used to test related workflows inside Elysia Tools.

💻 Turbo Monorepo Basic Setup json

🟢 simple ⭐⭐

Complete Turbo monorepo configuration with multiple applications and packages

⏱️ 20 min 🏷️ turbo, monorepo, setup
Prerequisites: Node.js, pnpm/yarn/npm, TypeScript
// Turbo Monorepo Basic Setup

// 1. Installation
// npm install turbo --save-dev
// or: pnpm add -D turbo
// or: yarn add -D turbo

// 2. package.json (Root)
{
  "name": "my-turbo-monorepo",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint",
    "test": "turbo run test",
    "clean": "turbo run clean && rm -rf node_modules",
    "format": "prettier --write "**/*.{ts,tsx,md}"",
    "changeset": "changeset",
    "version-packages": "changeset version",
    "release": "turbo run build --filter=!@repo/docs && changeset publish"
  },
  "devDependencies": {
    "turbo": "^2.0.0",
    "prettier": "^3.0.0",
    "changesets": "^2.26.0"
  },
  "packageManager": "[email protected]"
}

// 3. turbo.json - Root configuration
{
  "$schema": "https://turbo.build/schema.json",
  "globalEnv": [
    "NODE_ENV",
    "NEXT_PUBLIC_API_URL",
    "DATABASE_URL"
  ],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**", "dist/**", "!.next/**/(!*.next)"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"],
      "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]
    },
    "lint": {
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "clean": {
      "cache": false
    },
    "type-check": {
      "dependsOn": ["^build"]
    },
    "format": {
      "outputs": []
    }
  },
  "globalDependencies": [
    "**/.env.*local",
    "turbo.json",
    "package.json",
    "pnpm-lock.yaml",
    "yarn.lock",
    "npm-shrinkwrap.json"
  ]
}

// 4. Project structure
/*
my-turbo-monorepo/
├── apps/
│   ├── web/                    # Next.js frontend application
│   │   ├── package.json
│   │   ├── next.config.js
│   │   └── turbo.json
│   ├── api/                    # Backend API (Express/Fastify)
│   │   ├── package.json
│   │   └── turbo.json
│   └── docs/                   # Documentation site
│       ├── package.json
│       └── turbo.json
├── packages/
│   ├── ui/                     # Shared UI components
│   │   ├── package.json
│   │   ├── turbo.json
│   │   └── src/
│   ├── utils/                  # Shared utilities
│   │   ├── package.json
│   │   ├── turbo.json
│   │   └── src/
│   ├── config/                 # Shared configuration
│   │   ├── package.json
│   │   ├── eslint.config.js
│   │   ├── tsconfig.base.json
│   │   └── turbo.json
│   └── types/                  # Shared TypeScript types
│       ├── package.json
│       ├── turbo.json
│       └── src/
├── package.json
├── turbo.json
├── pnpm-workspace.yaml
└── .gitignore
*/

// 5. pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'

// 6. Example app configuration (apps/web/turbo.json)
{
  "extends": ["//"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {},
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    }
  }
}

// 7. Example package configuration (packages/ui/turbo.json)
{
  "extends": ["//"],
  "pipeline": {
    "build": {
      "outputs": ["dist/**"]
    },
    "lint": {},
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    }
  }
}

// 8. TypeScript configuration (packages/config/tsconfig.base.json)
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["dom", "dom.iterable", "ES2022"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "baseUrl": ".",
    "paths": {
      "@repo/ui": ["../../packages/ui/src"],
      "@repo/utils": ["../../packages/utils/src"],
      "@repo/types": ["../../packages/types/src"],
      "@repo/config/*": ["./"]
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],
  "exclude": ["node_modules"]
}

// 9. Environment variables (.env.example)
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"

# API
NEXT_PUBLIC_API_URL="http://localhost:3001/api"

# Authentication
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-secret-key"

# External services
REDIS_URL="redis://localhost:6379"
STRIPE_API_KEY="sk_test_..."
SENTRY_DSN="https://your-sentry-dsn"

💻 Turbo Multi-Application Workspace typescript

🟡 intermediate ⭐⭐⭐⭐

Advanced monorepo setup with Next.js frontend, Express backend, and shared packages

⏱️ 35 min 🏷️ turbo, monorepo, nextjs, express
Prerequisites: Turbo basics, Next.js, Express, TypeScript
// Turbo Multi-Application Workspace Example

// 1. Next.js Application (apps/web/package.json)
{
  "name": "@repo/web",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "next": "^14.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "@repo/ui": "workspace:*",
    "@repo/utils": "workspace:*",
    "@repo/types": "workspace:*",
    "axios": "^1.6.0",
    "next-auth": "^4.24.0"
  },
  "devDependencies": {
    "@repo/config/eslint": "workspace:*",
    "@repo/config/typescript": "workspace:*",
    "@types/node": "^20.0.0",
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.0",
    "autoprefixer": "^10.4.0",
    "postcss": "^8.4.0",
    "tailwindcss": "^3.3.0",
    "typescript": "^5.3.0"
  }
}

// 2. Next.js Configuration (apps/web/next.config.js)
const withTM = require('next-transpile-modules')([
  '@repo/ui',
  '@repo/utils',
  '@repo/types'
])

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@repo/ui', '@repo/utils', '@repo/types'],
  experimental: {
    optimizePackageImports: ['@repo/ui']
  },
  images: {
    domains: ['example.com', 'images.unsplash.com']
  },
  env: {
    CUSTOM_KEY: process.env.CUSTOM_KEY
  }
}

module.exports = nextConfig

// 3. Express Backend Application (apps/api/package.json)
{
  "name": "@repo/api",
  "version": "0.1.0",
  "private": true,
  "main": "dist/index.js",
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "lint": "eslint src --max-warnings 0",
    "test": "jest",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "express": "^4.18.0",
    "cors": "^2.8.0",
    "helmet": "^7.1.0",
    "compression": "^1.7.0",
    "morgan": "^1.10.0",
    "@repo/utils": "workspace:*",
    "@repo/types": "workspace:*",
    "zod": "^3.22.0",
    "prisma": "^5.6.0"
  },
  "devDependencies": {
    "@repo/config/eslint": "workspace:*",
    "@repo/config/typescript": "workspace:*",
    "@types/express": "^4.17.0",
    "@types/cors": "^2.8.0",
    "@types/compression": "^1.7.0",
    "@types/morgan": "^1.9.0",
    "tsx": "^4.6.0",
    "typescript": "^5.3.0"
  }
}

// 4. Express Application (apps/api/src/index.ts)
import express from 'express'
import cors from 'cors'
import helmet from 'helmet'
import compression from 'compression'
import morgan from 'morgan'
import { logger } from '@repo/utils/logger'
import { ApiResponse } from '@repo/types/api'

const app = express()
const PORT = process.env.PORT || 3001

// Middleware
app.use(helmet())
app.use(compression())
app.use(cors({
  origin: process.env.FRONTEND_URL || 'http://localhost:3000',
  credentials: true
}))
app.use(morgan('combined'))
app.use(express.json({ limit: '10mb' }))
app.use(express.urlencoded({ extended: true }))

// Health check endpoint
app.get('/health', (req, res): ApiResponse => {
  return res.json({
    success: true,
    message: 'API is healthy',
    timestamp: new Date().toISOString()
  })
})

// API routes
app.get('/api/users', async (req, res) => {
  try {
    // Simulate database call
    const users = [
      { id: 1, name: 'John Doe', email: '[email protected]' },
      { id: 2, name: 'Jane Smith', email: '[email protected]' }
    ]

    return res.json({
      success: true,
      data: users,
      count: users.length
    })
  } catch (error) {
    logger.error('Error fetching users:', error)
    return res.status(500).json({
      success: false,
      message: 'Internal server error'
    })
  }
})

// Error handling middleware
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
  logger.error('Unhandled error:', err)

  return res.status(500).json({
    success: false,
    message: 'Internal server error'
  })
})

app.listen(PORT, () => {
  logger.info(`API server running on port ${PORT}`)
})

const exportedApiApp = app

// 5. Shared UI Components Package (packages/ui/package.json)
{
  "name": "@repo/ui",
  "version": "0.1.0",
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.js",
      "types": "./dist/index.d.ts"
    },
    "./styles.css": "./dist/styles.css"
  },
  "files": ["dist"],
  "scripts": {
    "build": "tsup",
    "dev": "tsup --watch",
    "lint": "eslint src --max-warnings 0",
    "test": "jest",
    "type-check": "tsc --noEmit",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "clsx": "^2.0.0",
    "tailwind-merge": "^2.0.0",
    "@repo/types": "workspace:*"
  },
  "devDependencies": {
    "@repo/config/eslint": "workspace:*",
    "@repo/config/typescript": "workspace:*",
    "@storybook/addon-essentials": "^7.5.0",
    "@storybook/react": "^7.5.0",
    "@storybook/react-vite": "^7.5.0",
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.0",
    "autoprefixer": "^10.4.0",
    "postcss": "^8.4.0",
    "tailwindcss": "^3.3.0",
    "tsup": "^7.2.0",
    "typescript": "^5.3.0"
  },
  "peerDependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}

// 6. UI Components Build Configuration (packages/ui/tsup.config.ts)
import { defineConfig } from 'tsup'

const uiTsupConfig = defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs', 'esm'],
  dts: true,
  splitting: false,
  sourcemap: true,
  clean: true,
  external: ['react', 'react-dom'],
  onSuccess: 'npm run build:css'
})

// 7. Shared Components (packages/ui/src/Button.tsx)
import React from 'react'
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'

export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'outline'
  size?: 'sm' | 'md' | 'lg'
  loading?: boolean
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant = 'primary', size = 'md', loading, children, disabled, ...props }, ref) => {
    const baseStyles = 'inline-flex items-center justify-center font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2'

    const variants = {
      primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',
      secondary: 'bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500',
      outline: 'border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 focus:ring-blue-500'
    }

    const sizes = {
      sm: 'px-3 py-1.5 text-sm',
      md: 'px-4 py-2 text-sm',
      lg: 'px-6 py-3 text-base'
    }

    return (
      <button
        className={clsx(
          baseStyles,
          variants[variant],
          sizes[size],
          (loading || disabled) && 'opacity-50 cursor-not-allowed',
          className
        )}
        disabled={loading || disabled}
        ref={ref}
        {...props}
      >
        {loading && (
          <svg className="animate-spin -ml-1 mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
          </svg>
        )}
        {children}
      </button>
    )
  }
)

Button.displayName = 'Button'

export { Button }

// 8. Shared Utilities Package (packages/utils/src/logger.ts)
export type LogLevel = 'debug' | 'info' | 'warn' | 'error'

export interface LogEntry {
  level: LogLevel
  message: string
  timestamp: Date
  metadata?: Record<string, any>
}

export class Logger {
  private level: LogLevel = 'info'

  setLevel(level: LogLevel) {
    this.level = level
  }

  private shouldLog(level: LogLevel): boolean {
    const levels: Record<LogLevel, number> = {
      debug: 0,
      info: 1,
      warn: 2,
      error: 3
    }

    return levels[level] >= levels[this.level]
  }

  private log(level: LogLevel, message: string, metadata?: Record<string, any>) {
    if (!this.shouldLog(level)) return

    const entry: LogEntry = {
      level,
      message,
      timestamp: new Date(),
      metadata
    }

    if (process.env.NODE_ENV === 'development') {
      console[level](message, metadata || '')
    } else {
      // In production, you might want to send logs to a service
      console.log(JSON.stringify(entry))
    }
  }

  debug(message: string, metadata?: Record<string, any>) {
    this.log('debug', message, metadata)
  }

  info(message: string, metadata?: Record<string, any>) {
    this.log('info', message, metadata)
  }

  warn(message: string, metadata?: Record<string, any>) {
    this.log('warn', message, metadata)
  }

  error(message: string, metadata?: Record<string, any>) {
    this.log('error', message, metadata)
  }
}

export const logger = new Logger()

// 9. Shared Types (packages/types/src/api.ts)
export interface ApiResponse<T = any> {
  success: boolean
  data?: T
  message?: string
  error?: string
  timestamp?: string
}

export interface PaginatedResponse<T> extends ApiResponse<T[]> {
  pagination: {
    page: number
    limit: number
    total: number
    totalPages: number
  }
}

export interface ApiError {
  code: string
  message: string
  field?: string
}

// 10. Shared Types (packages/types/src/user.ts)
export interface User {
  id: number
  name: string
  email: string
  avatar?: string
  role: UserRole
  createdAt: string
  updatedAt: string
}

export type UserRole = 'admin' | 'user' | 'moderator'

export interface CreateUserRequest {
  name: string
  email: string
  role?: UserRole
}

export interface UpdateUserRequest {
  name?: string
  email?: string
  role?: UserRole
}

💻 Turbo Advanced Workflows yaml

🔴 complex ⭐⭐⭐⭐⭐

Advanced Turbo workflows including caching, filtering, deployment, and CI/CD integration

⏱️ 45 min 🏷️ turbo, ci/cd, deployment, advanced
Prerequisites: Advanced Turbo, Docker, GitHub Actions, CI/CD
// Turbo Advanced Workflows and CI/CD

// 1. Advanced turbo.json with complex dependencies
{
  "$schema": "https://turbo.build/schema.json",
  "globalEnv": [
    "NODE_ENV",
    "NEXT_PUBLIC_API_URL",
    "DATABASE_URL",
    "STRIPE_API_KEY",
    "SENTRY_DSN"
  ],
  "globalPassThroughEnv": [
    "VERCEL_*",
    "AWS_*",
    "GITHUB_*"
  ],
  "pipeline": {
    "build": {
      "dependsOn": ["^build", "^db:generate"],
      "outputs": [
        "dist/**",
        ".next/**",
        "!.next/cache/**",
        "!.next/**/(!*.next)",
        "public/build/**"
      ],
      "env": ["NODE_ENV", "NEXT_PUBLIC_API_URL"],
      "inputs": ["src/**/*.tsx", "src/**/*.ts", "package.json"]
    },
    "db:generate": {
      "outputs": ["prisma/migrations/**", "node_modules/.prisma/**"],
      "inputs": ["prisma/schema.prisma", "package.json"]
    },
    "db:push": {
      "cache": false,
      "outputs": ["prisma/migrations/**"]
    },
    "db:migrate": {
      "cache": false,
      "outputs": ["prisma/migrations/**"]
    },
    "test": {
      "dependsOn": ["build", "db:generate"],
      "outputs": ["coverage/**", "test-results/**"],
      "inputs": [
        "src/**/*.tsx",
        "src/**/*.ts",
        "test/**/*.ts",
        "test/**/*.tsx",
        "jest.config.*"
      ],
      "passThroughEnv": ["CI"]
    },
    "test:watch": {
      "cache": false,
      "persistent": true,
      "dependsOn": ["build"]
    },
    "lint": {
      "outputs": [],
      "inputs": ["src/**/*.tsx", "src/**/*.ts", "*.config.*"]
    },
    "lint:fix": {
      "cache": false,
      "outputs": []
    },
    "type-check": {
      "dependsOn": ["^build"],
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true,
      "dependsOn": ["db:generate"]
    },
    "clean": {
      "cache": false,
      "outputs": []
    },
    "format": {
      "outputs": [],
      "inputs": [
        "**/*.{ts,tsx,js,jsx,json,md,css,scss}",
        ".prettierrc*"
      ]
    },
    "storybook": {
      "cache": false,
      "persistent": true,
      "dependsOn": ["build"]
    },
    "build-storybook": {
      "dependsOn": ["build"],
      "outputs": ["storybook-static/**"]
    },
    "deploy": {
      "dependsOn": ["build", "test", "lint"],
      "cache": false
    },
    "size-limit": {
      "dependsOn": ["build"],
      "outputs": []
    },
    "bundlesize": {
      "dependsOn": ["build"],
      "outputs": []
    }
  }
}

// 2. GitHub Actions Workflow (.github/workflows/ci.yml)
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

env:
  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
  TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
  NODE_VERSION: 20
  PNPM_VERSION: 8

jobs:
  build:
    name: Build and Test
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18, 20]

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'pnpm'

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Get pnpm store directory
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

      - name: Setup pnpm cache
        uses: actions/cache@v3
        with:
          path: ${{ env.STORE_PATH }}
          key: pnpm-store-${{ runner.os }}-${{ matrix.node-version }}-${{ env.PNPM_VERSION }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            pnpm-store-${{ runner.os }}-${{ matrix.node-version }}-${{ env.PNPM_VERSION }}-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Generate database schema
        run: pnpm db:generate

      - name: Run type checking
        run: pnpm type-check

      - name: Run linting
        run: pnpm lint

      - name: Run tests
        run: pnpm test --coverage

      - name: Build packages and apps
        run: pnpm build

      - name: Check bundle sizes
        run: pnpm size-limit

      - name: Upload coverage reports
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage/lcov.info
          flags: unittests
          name: codecov-umbrella

  lint-pr:
    name: Lint Pull Request
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'pnpm'

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Run changesets
        uses: changesets/action@v1
        with:
          publish: pnpm changeset publish
          commit: 'chore: release packages'
          title: 'chore: release packages'

// 3. Deployment Script (scripts/deploy.sh)
#!/bin/bash

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Configuration
ENVIRONMENT=${1:-production}
APP_NAME="my-turbo-app"

echo -e "${GREEN}Starting deployment of ${APP_NAME} to ${ENVIRONMENT}${NC}"

# Step 1: Run tests
echo -e "${YELLOW}Running tests...${NC}"
pnpm test
echo -e "${GREEN}✓ Tests passed${NC}"

# Step 2: Build all packages
echo -e "${YELLOW}Building packages...${NC}"
pnpm build
echo -e "${GREEN}✓ Build completed${NC}"

# Step 3: Deploy based on environment
case ${ENVIRONMENT} in
  "production")
    echo -e "${YELLOW}Deploying to production...${NC}"

    # Deploy web app to Vercel
    echo "Deploying web app to Vercel..."
    cd apps/web
    npx vercel --prod --token $VERCEL_TOKEN
    cd ../..

    # Deploy API to Railway/Heroku
    echo "Deploying API to production..."
    cd apps/api
    # Railway deployment
    railway deploy
    cd ../..

    echo -e "${GREEN}✓ Production deployment completed${NC}"
    ;;

  "staging")
    echo -e "${YELLOW}Deploying to staging...${NC}"

    # Deploy web app to Vercel preview
    cd apps/web
    npx vercel --token $VERCEL_TOKEN
    cd ../..

    # Deploy API to staging
    cd apps/api
    # Staging deployment
    docker build -t ${APP_NAME}-api:staging .
    docker push ${DOCKER_REGISTRY}/${APP_NAME}-api:staging
    cd ../..

    echo -e "${GREEN}✓ Staging deployment completed${NC}"
    ;;

  *)
    echo -e "${RED}Unknown environment: ${ENVIRONMENT}${NC}"
    exit 1
    ;;
esac

echo -e "${GREEN}🚀 Deployment completed successfully!${NC}"

// 4. Docker Compose for Development (docker-compose.dev.yml)
version: '3.8'

services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: myapp_dev
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  minio:
    image: minio/minio:latest
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin123
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_data:/data

  api:
    build:
      context: .
      dockerfile: apps/api/Dockerfile.dev
    ports:
      - "3001:3001"
    environment:
      NODE_ENV: development
      DATABASE_URL: postgresql://postgres:postgres@postgres:5432/myapp_dev
      REDIS_URL: redis://redis:6379
    depends_on:
      - postgres
      - redis
    volumes:
      - ./apps/api:/app/apps/api
      - ./packages:/app/packages
      - /app/node_modules

  web:
    build:
      context: .
      dockerfile: apps/web/Dockerfile.dev
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: development
      NEXT_PUBLIC_API_URL: http://localhost:3001
    depends_on:
      - api
    volumes:
      - ./apps/web:/app/apps/web
      - ./packages:/app/packages
      - /app/node_modules

volumes:
  postgres_data:
  redis_data:
  minio_data:

// 5. API Dockerfile for Development (apps/api/Dockerfile.dev)
FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/api/package.json ./apps/api/
COPY packages/*/package.json ./packages/*/

# Install pnpm
RUN npm install -g pnpm

# Install dependencies
RUN pnpm install --frozen-lockfile

# Copy source code
COPY apps/api ./apps/api
COPY packages ./packages

# Generate Prisma client
RUN pnpm db:generate

EXPOSE 3001

CMD ["pnpm", "dev"]

// 6. Web Dockerfile for Development (apps/web/Dockerfile.dev)
FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/web/package.json ./apps/web/
COPY packages/*/package.json ./packages/*/

# Install pnpm
RUN npm install -g pnpm

# Install dependencies
RUN pnpm install --frozen-lockfile

# Copy source code
COPY apps/web ./apps/web
COPY packages ./packages

EXPOSE 3000

CMD ["pnpm", "dev"]

// 7. Size Limit Configuration (size-limit.json)
[
  {
    "name": "Web App Bundle",
    "path": "apps/web/.next/static/chunks/**/*.js",
    "limit": "1 MB",
    "ignore": [
      "**/node_modules/**"
    ]
  },
  {
    "name": "API Bundle",
    "path": "apps/api/dist/**/*.js",
    "limit": "500 KB"
  },
  {
    "name": "UI Components",
    "path": "packages/ui/dist/**/*.js",
    "limit": "100 KB"
  },
  {
    "name": "Utils Package",
    "path": "packages/utils/dist/**/*.js",
    "limit": "50 KB"
  }
]

// 8. Advanced Package Scripts
{
  "scripts": {
    // Development workflows
    "dev:all": "concurrently "pnpm dev:web" "pnpm dev:api" "pnpm dev:storybook"",
    "dev:web": "turbo run dev --filter=@repo/web",
    "dev:api": "turbo run dev --filter=@repo/api",
    "dev:storybook": "turbo run storybook --filter=@repo/ui",

    // Build workflows
    "build:affected": "turbo run build --filter='...[origin/HEAD]'",
    "build:web": "turbo run build --filter=@repo/web",
    "build:api": "turbo run build --filter=@repo/api",

    // Test workflows
    "test:affected": "turbo run test --filter='...[origin/HEAD]'",
    "test:ci": "turbo run test --concurrency=1",
    "test:coverage": "turbo run test -- --coverage",

    // Quality assurance
    "lint:affected": "turbo run lint --filter='...[origin/HEAD]'",
    "type-check:affected": "turbo run type-check --filter='...[origin/HEAD]'",
    "quality-check": "pnpm lint && pnpm type-check && pnpm test && pnpm build",

    // Database workflows
    "db:generate": "turbo run db:generate",
    "db:push": "turbo run db:push",
    "db:migrate": "turbo run db:migrate",
    "db:reset": "pnpm db:push --force-reset",

    // Package management
    "clean": "turbo run clean && rm -rf node_modules",
    "reinstall": "pnpm clean && pnpm install",
    "update": "pnpm update -i -r && pnpm install",

    // Release workflows
    "changeset": "changeset",
    "version": "changeset version",
    "release": "pnpm build && pnpm test && changeset publish",

    // Deployment workflows
    "deploy:staging": "./scripts/deploy.sh staging",
    "deploy:production": "./scripts/deploy.sh production",

    // Performance monitoring
    "size-limit": "size-limit",
    "bundle-analyzer": "turbo run build --filter=@repo/web && npx @next/bundle-analyzer apps/web/.next"
  }
}