Agent Skill
2/7/2026monorepo-structure
Turborepo monorepo setup with Yarn workspaces, shared configs, and development workflows. Use this skill when working with monorepo setup, shared packages, workspace dependencies, or build orchestration.
S
survikrowa
7GitHub Stars
1Views
npx skills add Survikrowa/Game-Critique
SKILL.md
| Name | monorepo-structure |
| Description | Turborepo monorepo setup with Yarn workspaces, shared configs, and development workflows. Use this skill when working with monorepo setup, shared packages, workspace dependencies, or build orchestration. |
name: monorepo-structure description: Turborepo monorepo setup with Yarn workspaces, shared configs, and development workflows. Use this skill when working with monorepo setup, shared packages, workspace dependencies, or build orchestration. license: MIT
Monorepo Structure Skill
Overview
This skill covers the monorepo architecture, workspace management, and development workflows for the Game Critique project using Turborepo and Yarn workspaces.
Monorepo Architecture
Project Structure
Game-Critique/
├── .github/ # GitHub configs and workflows
│ └── skills/ # Copilot skills
├── apps/ # Application workspaces
│ ├── api/ # NestJS GraphQL API
│ ├── native/ # Expo React Native app
│ └── web/ # React admin panel
├── packages/ # Shared packages
│ └── typescript-config/ # Shared TypeScript configs
├── package.json # Root package.json
├── turbo.json # Turborepo configuration
├── yarn.lock # Yarn lockfile
└── compose.yml # Docker Compose setup
Package Manager: Yarn 4.5.3
Workspace Configuration
// package.json (root)
{
"private": true,
"workspaces": [
"./apps/*",
"./packages/*"
],
"packageManager": "yarn@4.5.3",
"engines": {
"node": ">=18"
}
}
Yarn Commands
# Install dependencies for all workspaces
yarn install
# Add dependency to specific workspace
yarn workspace api add @nestjs/graphql
yarn workspace web add @tanstack/react-query
yarn workspace native add tamagui
# Add dev dependency
yarn workspace api add -D jest
# Remove dependency
yarn workspace api remove @nestjs/graphql
# Run script in workspace
yarn workspace api dev
yarn workspace web build
# Run script in all workspaces
yarn workspaces foreach run build
yarn workspaces foreach run test
# Interactive upgrade
yarn upgrade-interactive
Turborepo Configuration
Basic Setup
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"tasks": {
"build": {
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"dependsOn": ["^build"]
},
"dev": {
"cache": false,
"persistent": true
},
"test": {
"cache": false,
"persistent": false
},
"lint": {
"outputs": []
},
"clean": {
"cache": false
}
}
}
Task Orchestration
Build Dependencies:
^buildmeans "build dependencies first"- Ensures packages are built before apps that depend on them
Caching:
cache: falsefor dev servers and testspersistent: truefor long-running processes- Outputs specified for build artifacts
Turborepo Commands
# Run tasks across all workspaces
turbo run build # Build all apps
turbo run dev # Start all dev servers
turbo run test # Run all tests
turbo run lint # Lint all code
# Run task for specific workspace
turbo run build --filter=api
turbo run dev --filter=web
turbo run test --filter=native
# Run task for multiple workspaces
turbo run dev --filter=web --filter=api
# Force run (ignore cache)
turbo run build --force
# Clear cache
turbo run clean
Root Scripts
// package.json (root)
{
"scripts": {
"dev": "turbo run dev",
"dev:web": "turbo run dev --filter=web --filter=api",
"dev:api": "turbo run dev --filter=api",
"build": "turbo run build",
"test": "turbo run test",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\" --ignore-path .gitignore",
"clean": "turbo run clean && rm -rf node_modules"
}
}
Shared Packages
TypeScript Configuration Package
packages/
typescript-config/
├── package.json
├── base.json # Base config
├── nestjs.json # NestJS-specific
├── nextjs.json # Next.js-specific
└── react-native-library.json
Package.json:
{
"name": "@repo/typescript-config",
"version": "0.0.0",
"private": true,
"files": [
"base.json",
"nestjs.json",
"nextjs.json",
"react-native-library.json"
]
}
Base Config:
// packages/typescript-config/base.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}
NestJS Config:
// packages/typescript-config/nestjs.json
{
"extends": "./base.json",
"compilerOptions": {
"module": "commonjs",
"target": "ES2021",
"lib": ["ES2021"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"incremental": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"strictPropertyInitialization": false
}
}
Using Shared Config
// apps/api/tsconfig.json
{
"extends": "@repo/typescript-config/nestjs.json",
"compilerOptions": {
"outDir": "./dist",
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Workspace Dependencies
Internal Workspace References
// apps/api/package.json
{
"name": "api",
"dependencies": {
"@repo/typescript-config": "*"
}
}
Version Management
- Use
*for internal workspace dependencies - Yarn resolves to local workspace automatically
- Changes to packages immediately available to apps
Development Workflows
Starting Development Environment
Full Stack:
# Start all services
yarn dev
# API + Web only
yarn dev:web
# API only
yarn dev:api
Individual Apps:
# API with database
cd apps/api
yarn start:db # Start PostgreSQL + Redis
yarn dev # Start API in watch mode
# Web admin panel
cd apps/web
yarn dev # Starts on port 5173
# Native mobile app
cd apps/native
yarn dev-local # With local API
yarn dev # With production API
Building for Production
# Build all apps
yarn build
# Build specific app
cd apps/api && yarn build
cd apps/web && yarn build
# Build with Turborepo
turbo run build --filter=api
turbo run build --filter=web
Code Quality
# Lint all workspaces
yarn lint
# Format all code
yarn format
# Workspace-specific
cd apps/api && yarn lint
cd apps/web && yarn format
Environment Variables
Organization
apps/
api/
.env
.env.local
.env.example
web/
.env
.env.local
native/
.env.local
.env.production
Loading Environment Variables
API (NestJS):
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
],
})
export class AppModule {}
Web (Vite):
// Access with import.meta.env
const apiUrl = import.meta.env.VITE_API_URL;
Native (Expo):
// Access with process.env.EXPO_PUBLIC_*
const apiUrl = process.env.EXPO_PUBLIC_GRAPHQL_ENDPOINT;
Turbo Global Dependencies
// turbo.json
{
"globalDependencies": ["**/.env.*local"]
}
This ensures Turbo cache is invalidated when env files change.
Docker Compose Integration
Root Compose File
# compose.yml (root)
name: game-critique
include:
- path: apps/api/compose.yml
API Services
# apps/api/compose.yml
services:
postgres:
image: postgres:15
ports:
- "5432:5432"
environment:
POSTGRES_USER: game_critique
POSTGRES_PASSWORD: password
POSTGRES_DB: game_critique
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
Docker Commands
# Start services (from root or apps/api)
docker-compose up -d
# Stop services
docker-compose down
# View logs
docker-compose logs -f postgres
docker-compose logs -f redis
# Reset databases
docker-compose down -v # Removes volumes
Git Hooks with Husky
Setup
// package.json (root)
{
"scripts": {
"prepare": "husky install"
},
"lint-staged": {
"*.{ts,tsx}": [
"prettier --write"
]
}
}
Pre-commit Hook
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
GraphQL Schema Sharing
Configuration
# graphql.config.yml (root)
schema: "apps/api/src/schema.gql"
Workflow
- API generates schema on startup
- Schema file at
apps/api/src/schema.gql - Web and Native reference this schema for codegen
- IDE uses schema for autocomplete
// apps/web/codegen-dev.ts
const config: CodegenConfig = {
schema: "http://localhost:3001/graphql", // Or file path
documents: "src/**/*.graphql",
// ...
};
// apps/native/codegen.ts
const config: CodegenConfig = {
schema: process.env.EXPO_PUBLIC_GRAPHQL_ENDPOINT,
documents: ["modules/**/*.graphql"],
// ...
};
Adding a New Workspace
1. Create Workspace Directory
mkdir -p apps/new-app
cd apps/new-app
2. Initialize Package
yarn init -p
3. Configure Package.json
{
"name": "new-app",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "...",
"build": "...",
"test": "..."
},
"dependencies": {
"@repo/typescript-config": "*"
}
}
4. Install Dependencies
# From root
yarn install
5. Add Turbo Task (if needed)
// turbo.json
{
"tasks": {
"new-task": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}
Creating Shared Packages
1. Create Package Structure
mkdir -p packages/shared-utils
cd packages/shared-utils
2. Setup Package
// packages/shared-utils/package.json
{
"name": "@repo/shared-utils",
"version": "0.0.0",
"private": true,
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch"
},
"devDependencies": {
"@repo/typescript-config": "*",
"typescript": "^5.0.0"
}
}
3. TypeScript Config
// packages/shared-utils/tsconfig.json
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}
4. Export Functions
// packages/shared-utils/src/index.ts
export function formatDate(date: Date): string {
return date.toISOString();
}
export function slugify(text: string): string {
return text.toLowerCase().replace(/\s+/g, '-');
}
5. Build Package
cd packages/shared-utils
yarn build
6. Use in Apps
// apps/api/package.json
{
"dependencies": {
"@repo/shared-utils": "*"
}
}
// apps/api/src/some-file.ts
import { formatDate, slugify } from '@repo/shared-utils';
Troubleshooting
Dependency Issues
# Clear all node_modules
yarn clean
# Reinstall everything
yarn install
# Rebuild packages
turbo run build
Turbo Cache Issues
# Clear Turbo cache
turbo run build --force
# Or delete cache directory
rm -rf node_modules/.cache/turbo
Workspace Not Found
# Check workspace configuration
yarn workspaces list
# Verify package.json workspace paths
# Ensure package names match
Port Conflicts
# Find process using port
lsof -i :3000
lsof -i :5173
# Kill process
kill -9 <PID>
# Or change port in config
TypeScript Errors
# Rebuild TypeScript projects
turbo run build --filter=@repo/typescript-config
turbo run build
# Restart TypeScript server in IDE
# VSCode: Cmd+Shift+P -> "TypeScript: Restart TS Server"
Best Practices
1. Use Workspace Protocol
// Use * for internal dependencies
"dependencies": {
"@repo/typescript-config": "*" // ✅ Good
"@repo/typescript-config": "1.0.0" // ❌ Bad
}
2. Keep Root Clean
- Only workspace orchestration in root
- App-specific code in workspaces
- Shared utilities in packages
3. Consistent Naming
- Apps: descriptive names (api, web, native)
- Packages: scoped with @repo/* prefix
- Scripts: consistent across workspaces
4. Proper Caching
- Enable cache for builds
- Disable cache for dev servers
- Specify outputs for cached tasks
5. Environment Isolation
- Each app manages its own env vars
- Use different prefixes (VITE_, EXPO_PUBLIC_)
- Never commit .env.local files
6. Build Order
- Use
dependsOnfor build dependencies - Shared packages build before apps
- Parallelize independent builds
7. Version Pinning
- Pin external dependencies to exact versions
- Use workspace protocol for internal deps
- Document major version upgrades
Development Commands Reference
# Root level
yarn install # Install all dependencies
yarn dev # Start all apps
yarn dev:web # Start web + api
yarn dev:api # Start api only
yarn build # Build all apps
yarn lint # Lint all code
yarn format # Format all code
yarn clean # Clean all workspaces
# Workspace level
yarn workspace api dev
yarn workspace web build
yarn workspace native test
# Turbo commands
turbo run build
turbo run dev --filter=api
turbo run test --filter=web --filter=api
turbo run build --force
# Docker
docker-compose up -d
docker-compose down
docker-compose logs -f
# Yarn workspaces
yarn workspaces list
yarn workspaces foreach run build
yarn workspace api add lodash
CI/CD Considerations
Caching Strategy
# .github/workflows/ci.yml
- name: Setup Turbo cache
uses: actions/cache@v3
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
Affected Apps Only
# Build only changed apps
turbo run build --filter=[HEAD^1]
# Test affected apps
turbo run test --filter=[main...HEAD]
Parallel Jobs
strategy:
matrix:
app: [api, web, native]
steps:
- run: turbo run build --filter=${{ matrix.app }}
Skills Info
Original Name:monorepo-structureAuthor:survikrowa
Download