# Turborepo Setup & Configuration Installation, workspace configuration, and project structure for monorepos. ## Installation ### Create New Monorepo Using official starter: ```bash npx create-turbo@latest my-monorepo cd my-monorepo ``` Interactive prompts: - Project name - Package manager (npm, yarn, pnpm, bun) - Example template ### Manual Installation Install in existing project: ```bash # npm npm install turbo --save-dev # yarn yarn add turbo --dev # pnpm pnpm add turbo --save-dev # bun bun add turbo --dev ``` ## Workspace Configuration ### Package Manager Setup **pnpm (recommended):** ```yaml # pnpm-workspace.yaml packages: - 'apps/*' - 'packages/*' ``` **npm/yarn:** ```json // package.json (root) { "name": "my-monorepo", "private": true, "workspaces": [ "apps/*", "packages/*" ] } ``` ### Root Package.json ```json { "name": "my-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" }, "devDependencies": { "turbo": "latest", "typescript": "^5.0.0" }, "packageManager": "pnpm@8.0.0" } ``` ## Project Structure ### Recommended Directory Structure ``` my-monorepo/ ├── apps/ # Applications │ ├── web/ # Next.js web app │ │ ├── app/ │ │ ├── package.json │ │ └── next.config.js │ ├── docs/ # Documentation site │ │ ├── app/ │ │ └── package.json │ └── api/ # Backend API │ ├── src/ │ └── package.json ├── packages/ # Shared packages │ ├── ui/ # UI component library │ │ ├── src/ │ │ ├── package.json │ │ └── tsconfig.json │ ├── config/ # Shared configs │ │ ├── eslint/ │ │ └── typescript/ │ ├── utils/ # Utility functions │ │ ├── src/ │ │ └── package.json │ └── types/ # Shared TypeScript types │ ├── src/ │ └── package.json ├── turbo.json # Turborepo config ├── package.json # Root package.json ├── pnpm-workspace.yaml # Workspace config (pnpm) └── .gitignore ``` ## Application Package Setup ### Next.js App ```json // apps/web/package.json { "name": "web", "version": "1.0.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@repo/ui": "*", "@repo/utils": "*", "next": "latest", "react": "latest", "react-dom": "latest" }, "devDependencies": { "@repo/typescript-config": "*", "@repo/eslint-config": "*", "typescript": "^5.0.0" } } ``` ### Backend API App ```json // apps/api/package.json { "name": "api", "version": "1.0.0", "private": true, "scripts": { "dev": "tsx watch src/index.ts", "build": "tsup src/index.ts", "start": "node dist/index.js", "lint": "eslint src/" }, "dependencies": { "@repo/utils": "*", "@repo/types": "*", "express": "^4.18.0" }, "devDependencies": { "@repo/typescript-config": "*", "@types/express": "^4.17.0", "tsx": "^4.0.0", "tsup": "^8.0.0" } } ``` ## Shared Package Setup ### UI Component Library ```json // packages/ui/package.json { "name": "@repo/ui", "version": "0.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./button": { "types": "./dist/button.d.ts", "default": "./dist/button.js" } }, "scripts": { "build": "tsc", "dev": "tsc --watch", "lint": "eslint src/", "clean": "rm -rf dist" }, "dependencies": { "react": "latest" }, "devDependencies": { "@repo/typescript-config": "*", "typescript": "^5.0.0" } } ``` ```json // packages/ui/tsconfig.json { "extends": "@repo/typescript-config/react-library.json", "compilerOptions": { "outDir": "dist", "declarationDir": "dist" }, "include": ["src"], "exclude": ["node_modules", "dist"] } ``` ### Utility Library ```json // packages/utils/package.json { "name": "@repo/utils", "version": "0.0.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "jest" }, "devDependencies": { "@repo/typescript-config": "*", "jest": "^29.0.0", "typescript": "^5.0.0" } } ``` ## Shared Configuration Packages ### TypeScript Config Package ``` packages/typescript-config/ ├── base.json ├── nextjs.json ├── react-library.json └── package.json ``` ```json // packages/typescript-config/package.json { "name": "@repo/typescript-config", "version": "0.0.0", "main": "base.json", "files": [ "base.json", "nextjs.json", "react-library.json" ] } ``` ```json // packages/typescript-config/base.json { "compilerOptions": { "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "isolatedModules": true, "moduleResolution": "bundler", "target": "ES2020", "module": "ESNext" }, "exclude": ["node_modules"] } ``` ```json // packages/typescript-config/nextjs.json { "extends": "./base.json", "compilerOptions": { "jsx": "preserve", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "noEmit": true, "incremental": true, "plugins": [{ "name": "next" }] }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] } ``` ### ESLint Config Package ``` packages/eslint-config/ ├── library.js ├── next.js └── package.json ``` ```json // packages/eslint-config/package.json { "name": "@repo/eslint-config", "version": "0.0.0", "main": "library.js", "files": ["library.js", "next.js"], "dependencies": { "eslint-config-next": "latest", "eslint-config-prettier": "^9.0.0", "eslint-plugin-react": "latest" } } ``` ```js // packages/eslint-config/library.js module.exports = { extends: ['eslint:recommended', 'prettier'], env: { node: true, es2020: true, }, parserOptions: { ecmaVersion: 2020, sourceType: 'module', }, rules: { 'no-console': 'warn', }, } ``` ```js // packages/eslint-config/next.js module.exports = { extends: ['next', 'prettier'], rules: { '@next/next/no-html-link-for-pages': 'off', }, } ``` ## Dependency Management ### Internal Dependencies Use workspace protocol: **pnpm:** ```json { "dependencies": { "@repo/ui": "workspace:*" } } ``` **npm/yarn:** ```json { "dependencies": { "@repo/ui": "*" } } ``` ### Version Syncing Keep dependencies in sync across packages: ```json // Root package.json { "devDependencies": { "react": "18.2.0", "react-dom": "18.2.0", "typescript": "5.0.0" } } ``` Packages inherit from root or specify versions explicitly. ## Turbo.json Configuration Basic configuration file: ```json { "$schema": "https://turbo.build/schema.json", "globalDependencies": [ "**/.env.*local", "tsconfig.json" ], "globalEnv": [ "NODE_ENV" ], "pipeline": { "build": { "dependsOn": ["^build"], "outputs": [".next/**", "!.next/cache/**", "dist/**"] }, "dev": { "cache": false, "persistent": true }, "lint": { "dependsOn": ["^build"] }, "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] }, "clean": { "cache": false } } } ``` ## Environment Variables ### Global Environment Variables ```json // turbo.json { "globalEnv": [ "NODE_ENV", "CI" ] } ``` ### Package-Specific Environment Variables ```json { "pipeline": { "build": { "env": ["NEXT_PUBLIC_API_URL", "DATABASE_URL"], "passThroughEnv": ["CUSTOM_VAR"] } } } ``` ### .env Files ``` my-monorepo/ ├── .env # Global env vars ├── .env.local # Local overrides (gitignored) ├── apps/ │ └── web/ │ ├── .env # App-specific │ └── .env.local # Local overrides ``` ## Gitignore Configuration ```gitignore # Dependencies node_modules/ .pnp .pnp.js # Turbo .turbo # Build outputs dist/ .next/ out/ build/ # Environment .env.local .env.*.local # Testing coverage/ # Misc .DS_Store *.log ``` ## NPM Scripts Common scripts in root package.json: ```json { "scripts": { "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", "test": "turbo run test", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "clean": "turbo run clean && rm -rf node_modules", "typecheck": "turbo run typecheck" } } ``` ## Initialization Checklist Setting up new Turborepo: - [ ] Install Turborepo (create-turbo or manual) - [ ] Configure workspace (pnpm-workspace.yaml or package.json) - [ ] Create directory structure (apps/, packages/) - [ ] Set up shared config packages (typescript-config, eslint-config) - [ ] Create turbo.json with pipeline - [ ] Configure gitignore - [ ] Set up environment variables - [ ] Define package dependencies - [ ] Add root scripts - [ ] Test build and dev commands