Monorepo Structure
Turborepo-based monorepo architecture for code reuse, unified tooling, and simplified dependency management.
All applications and packages are organized in a single repository using Turborepo for orchestration. This structure enables shared code, consistent tooling, and simplified dependency management across frontend and backend applications.
Overview
All applications and packages coexist in one repository with clear organizational boundaries:
apps/- Applications (API, Web, Docs, etc.)packages/- Shared packages (types, contracts, core, react, ui, etc.)contracts/- Smart contract code (EVM, Solana)infra/- Infrastructure as code (Pulumi)
Why Monorepo?
We chose a monorepo over standalone repositories for several key benefits:
- ✅ Code reuse - Shared UI components, types, and utilities across apps
- ✅ Unified tooling - Consistent linting, formatting, and build standards
- ✅ Faster CI/CD - Turborepo caching speeds up builds and tests
- ✅ Simplified dependencies - Automatic synchronization across workspace packages
- ✅ Better DX - Single repository, consistent developer experience
Package Dependency Graph
flowchart TB
subgraph Packages["packages/"]
Types["types<br/>(pure TS domain)"]
Core["core<br/>(generated hey-api client)"]
React["react<br/>(TanStack Query)"]
UI["ui<br/>(Shadcn components)"]
end
subgraph Apps["apps/"]
API["api<br/>(Fastify + OpenAPI)"]
Web["web<br/>(Next.js)"]
Docs["docs<br/>(Fumadocs)"]
end
Types --> Core
API -->|OpenAPI| Core
Core --> React
React --> Web
Core --> Web
UI --> Web
UI --> Docs
Web -->|HTTP| APITurborepo Benefits
Turborepo orchestrates builds and provides intelligent caching:
- Task caching - Only rebuilds what changed
- Parallel execution - Runs independent tasks simultaneously
- Remote caching - Share cache across team and CI/CD
- Pipeline configuration - Define task dependencies and execution order
Package Organization
Applications (apps/)
Each application is self-contained but can import shared packages:
apps/api- Fastify backend APIapps/web- Next.js frontend applicationapps/docs- Documentation site (Fumadocs)
Shared Packages (packages/)
Packages follow strict dependency rules:
types- Pure TypeScript domain types (no runtime dependencies)core- Generated runtime-agnostic API client (via hey-api from OpenAPI)react- React-specific hooks and TanStack Query integration (generated via hey-api)ui- Shared UI components (Shadcn/ui based)
Dependency Direction
Strict one-way dependencies prevent circular references:
types → core → react
↑
apps/api (OpenAPI)
↓
apps/webWorkspace Configuration
The monorepo uses pnpm workspaces for dependency management:
workspace:*protocol for internal package dependencies- Symlink-based resolution for fast local development
- Proper hoisting of shared dependencies
Development Workflow
- Local development - Direct TypeScript imports (no build step)
- Package builds -
tsupcompiles packages to ESM for publishing - CI/CD - Turborepo orchestrates builds with intelligent caching
- Publishing -
prepackscripts switch exports todist/for npm
Related Documentation
- Package Architecture - Detailed package conventions
- Monorepo Structure - Architecture details