-
Notifications
You must be signed in to change notification settings - Fork 1
Turborepo Architecture
UABC Web uses Turborepo as our monorepo build system. This document explains the architecture, concepts, benefits, and how to work with our Turborepo setup.
- Overview
- What is Turborepo?
- Project Structure
- Key Benefits
- Package Architecture
- Working with Turborepo
- Configuration Files
- Best Practices
- Troubleshooting
- Additional Resources
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
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.
-
Shared Dependencies: All projects use the same version of dependencies, preventing version conflicts.
-
Code Sharing: Common code like UI components, themes, and configurations are shared between apps.
-
Efficient Builds:
- Turborepo only rebuilds what changed
- Parallel execution of tasks
- Local and remote caching for faster builds
-
Consistent Development:
- Shared ESLint, TypeScript, and testing configurations
- Unified coding standards across the monorepo
-
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
-
ui/
- Reusable React components
- Storybook integration for component development
- Component testing setup
-
theme/
- Shared design tokens
- Color schemes
- Typography settings
- Component-specific themes
-
typescript-config/
- Base TypeScript configuration
- Next.js specific config
- React library config
-
test-config/
- Shared testing utilities
- Test setup files
- Common test helpers
-
tailwind-config/
- Shared Tailwind CSS configuration
- Custom plugins and extensions
# 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 -
--filter "!backend"
- Run command for everything except backend
- Create a new directory in
packages/
- Add package.json with necessary dependencies
- Update root
turbo.json
if needed - Run
pnpm install
to update dependencies
To use a workspace package in another package:
{
"dependencies": {
"@repo/ui": "workspace:*",
"@repo/theme": "workspace:*"
}
}
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
}
}
}
Defines the workspace structure:
packages:
- 'apps/*'
- 'packages/*'
-
Package Organization
- Keep related code together in packages
- Use clear, descriptive package names
- Document package APIs and usage
-
Dependencies
- Use
workspace:*
for internal dependencies - Keep shared dependencies in root
package.json
- Regularly update dependencies
- Use
-
Task Pipeline
- Define clear task dependencies
- Use appropriate cache settings
- Keep build outputs clean
-
Code Sharing
- Create shared packages for common code
- Use TypeScript for better type safety
- Write tests for shared code
Common issues and solutions:
-
Dependency Issues
# Clean install pnpm clean pnpm install
-
Build Failures
- Check task dependencies in turbo.json
- Verify package.json scripts
- Check for missing dependencies