Skip to content

Turborepo Architecture

taroj1205 edited this page Apr 28, 2025 · 5 revisions

Overview

UABC Web uses Turborepo as our monorepo build system. This document explains the architecture, concepts, benefits, and how to work with our Turborepo setup.

Table of Contents

What is Turborepo?

Turborepo is a high-performance build system for JavaScript/TypeScript monorepos. It provides:

  • Incremental builds
  • Smart caching
  • Parallel execution
  • Task dependencies
  • Cloud caching
  • Efficient dependency management

Project Structure

Our monorepo is organized as follows:

uabc-web/
├── apps/                 # Application code
│   ├── backend/         # Payload CMS
│   └── frontend/        # Next.js frontend
├── packages/            # Shared packages
│   ├── tailwind-config/ # Shared Tailwind configuration
│   ├── test-config/     # Testing utilities and setup
│   ├── theme/           # Shared theme configuration
│   ├── typescript-config/ # Shared TypeScript configs
│   └── ui/              # Shared UI components

Checkout https://llm.taroj1205.workers.dev/UoAWDCC/uabc-web for full structure of the repository.

Key Benefits

  1. Shared Dependencies: All projects use the same version of dependencies, preventing version conflicts.

  2. Code Sharing: Common code like UI components, themes, and configurations are shared between apps.

  3. Efficient Builds:

    • Turborepo only rebuilds what changed
    • Parallel execution of tasks
    • Local and remote caching for faster builds
  4. Consistent Development:

    • Shared ESLint, TypeScript, and testing configurations
    • Unified coding standards across the monorepo

Package Architecture

Apps

  • backend: Payload CMS application

    • Handles authentication, data management, and API
    • Contains collections, services, and API routes
  • frontend: Next.js application

    • User-facing web interface
    • Uses shared UI components and theme
    • Implements business logic and state management

Shared Packages

  1. ui/

    • Reusable React components
    • Storybook integration for component development
    • Component testing setup
  2. theme/

    • Shared design tokens
    • Color schemes
    • Typography settings
    • Component-specific themes
  3. typescript-config/

    • Base TypeScript configuration
    • Next.js specific config
    • React library config
  4. test-config/

    • Shared testing utilities
    • Test setup files
    • Common test helpers
  5. tailwind-config/

    • Shared Tailwind CSS configuration
    • Custom plugins and extensions

Working with Turborepo

Key Commands

# Install dependencies
pnpm install

# Development
pnpm dev                          # Run all apps in development mode
pnpm dev --filter frontend       # Run only frontend
pnpm dev --filter backend        # Run only backend

# Building
pnpm build                        # Build all packages and apps
pnpm build --filter frontend     # Build frontend only
pnpm build --filter backend      # Build backend only

# Testing
pnpm test                         # Run all tests
pnpm test --filter frontend      # Test frontend only
pnpm test --filter backend       # Test backend only

# Other useful filter commands
pnpm lint --filter frontend      # Lint frontend only
pnpm check-types --filter backend  # Check types backend only

Note: The --filter flag allows you to run commands for specific workspaces. You can also use patterns like:

  • --filter "./apps/*" - Run command for all apps
  • --filter "./packages/*" - Run command for all packages

Adding New Packages

  1. Create a new directory in packages/
  2. Add package.json with necessary dependencies
  3. Update root turbo.json if needed
  4. Run pnpm install to update dependencies

Workspace Dependencies

To use a workspace package in another package:

{
  "dependencies": {
    "@repo/ui": "workspace:*",
    "@repo/theme": "workspace:*"
  }
}

Configuration Files

turbo.json

The root turbo.json defines the task pipeline and dependencies:

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["**/.env.*local"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

pnpm-workspace.yaml

Defines the workspace structure:

packages:
  - 'apps/*'
  - 'packages/*'

Best Practices

  1. Package Organization

    • Keep related code together in packages
    • Use clear, descriptive package names
    • Document package APIs and usage
  2. Dependencies

    • Use workspace:* for internal dependencies
    • Keep shared dependencies in root package.json
    • Regularly update dependencies
  3. Task Pipeline

    • Define clear task dependencies
    • Use appropriate cache settings
    • Keep build outputs clean
  4. Code Sharing

    • Create shared packages for common code
    • Use TypeScript for better type safety
    • Write tests for shared code

Troubleshooting

Common issues and solutions:

  1. Dependency Issues

    # Clean install
    pnpm clean
    pnpm install
  2. Build Failures

    • Check task dependencies in turbo.json
    • Verify package.json scripts
    • Check for missing dependencies

Additional Resources

Clone this wiki locally