TABLE OF CONTENTS
Monorepo Strategies with Turborepo: Managing Enterprise Codebases at Scale

Enterprise engineering organizations face a fundamental code organization challenge: as applications grow from 5 projects to 50 projects, managing dependencies, coordinating deployments, and maintaining consistency becomes exponentially more complex.
For years, companies had two bad options: polyrepo (separate repositories for each project causing version hell and duplication) or monorepo (single repository for everything causing slow builds and tooling limitations).
Then Turborepo emerged as the build system that makes monorepos actually work at enterprise scale. Built by Vercel and used by companies like Netflix, Airbnb, and Microsoft, Turborepo solves the fundamental problems that made monorepos impractical: slow builds, complex caching, and coordinating tasks across dozens of projects.
At Askan Technologies, we’ve migrated 15+ enterprise organizations from polyrepo to monorepo with Turborepo over the past 24 months. These aren’t small projects. We’re talking about codebases with 30-100 applications, 200+ developers contributing daily, and CI/CD pipelines that must complete in minutes, not hours.
The results: 70-85% faster build times, 60% reduction in dependency conflicts, and 40% improvement in developer productivity compared to traditional polyrepo or basic monorepo setups.
This isn’t theoretical architecture. It’s production infrastructure supporting companies processing millions in transactions daily across US, UK, Australia, and Canada markets.
The Code Organization Crisis
Before exploring Turborepo solutions, let’s understand why code organization matters and how companies typically fail at it.
The Polyrepo Problem
Most companies start with polyrepo: separate Git repository for each application, library, or service.
Example polyrepo structure:
- web-app (customer-facing website)
- mobile-app (iOS/Android applications)
- admin-dashboard (internal tools)
- shared-ui-library (React components)
- shared-utils-library (helper functions)
- api-gateway (backend services)
- auth-service (authentication microservice)
- payment-service (payment processing)
Initial advantages:
- Clear ownership boundaries (each team owns their repo)
- Independent deployment (ship web app without touching mobile)
- Simple access control (restrict who can commit to what)
- Standard Git workflows (familiar to all developers)
Problems emerge as you scale:
- Dependency Hell
Shared UI library releases version 2.0. Now you must:
- Update web app to use 2.0
- Update mobile app to use 2.0
- Update admin dashboard to use 2.0
- Coordinate three separate PRs across three repos
- Manage version mismatches if one app doesn’t update
Real example: A client had 12 applications using a shared component library. A critical security fix required updating all 12 apps. The process took 3 weeks and 40 hours of developer time coordinating changes across repositories.
- Code Duplication
Each repo reinvents common patterns:
- Authentication logic (copied with slight variations)
- API client code (duplicated across web and mobile)
- Configuration files (similar ESLint, TypeScript configs repeated)
- CI/CD pipelines (nearly identical GitHub Actions across repos)
Impact: A client had the same authentication bug in 5 different repositories because the fix applied to one wasn’t propagated to others.
- Cross-Repo Changes Are Painful
Changing an API contract requires:
- Update API service (one repo)
- Update frontend to match (another repo)
- Update mobile app (third repo)
- Update documentation (fourth repo)
- Create 4 PRs, wait for 4 CI runs, coordinate 4 merges
Developer experience: “I spent 30 minutes making the change and 3 hours coordinating the deployment.”
- Inconsistent Tooling
Each repo has slightly different:
- Node.js versions (web app uses 18, mobile uses 16)
- Package managers (some use npm, others yarn, others pnpm)
- Linting rules (different ESLint configs)
- Testing frameworks (Jest vs Vitest vs Mocha)
Onboarding nightmare: New developers must learn 5 different repo setups instead of one consistent environment.
The Basic Monorepo Problem
Companies recognize polyrepo problems and consolidate into a monorepo: single Git repository containing all projects.
Structure:
monorepo/
apps/
web/
mobile/
admin/
packages/
ui-library/
utils/
api-client/
services/
api-gateway/
auth-service/
Advantages:
- Atomic changes (single PR updates API and all consumers)
- Shared tooling (one ESLint config, one TypeScript config)
- No version synchronization (packages always use latest)
- Easier refactoring (find all usages across entire codebase)
New problems without proper tooling:
- Slow Builds
Changing one line in shared UI library triggers:
- Rebuild of UI library (2 minutes)
- Rebuild of web app (5 minutes)
- Rebuild of mobile app (8 minutes)
- Rebuild of admin dashboard (4 minutes)
- Total: 19 minutes for one-line change
- Inefficient CI
CI runs everything on every commit:
- Test all packages (15 minutes)
- Test all apps (30 minutes)
- Lint everything (5 minutes)
- Total CI time: 50 minutes per PR
Even if you only changed the admin dashboard, CI tests the entire codebase.
- No Incremental Computation
Traditional monorepo tools rebuild from scratch every time:
- No caching of unchanged packages
- No parallelization across projects
- No awareness of dependency graph
Impact: A client’s monorepo without Turborepo took 45 minutes for CI. Developer wait time killed productivity.
Turborepo: The Enterprise Solution
Turborepo solves monorepo scaling problems through three core concepts: intelligent caching, task orchestration, and dependency-aware builds.
Core Concept 1: Remote Caching
Turborepo caches task outputs (builds, tests, lints) and shares them across machines.
How it works:
- Developer A runs build command
- Turborepo executes build, caches output
- Developer B pulls latest code (same as Developer A had)
- Developer B runs build command
- Turborepo retrieves cached output instead of rebuilding
- Build completes in 0.5 seconds instead of 5 minutes
Real impact:
| Scenario | Without Turborepo | With Turborepo |
| Fresh checkout, run tests | 18 minutes | 18 minutes (first run) |
| Teammate runs same tests | 18 minutes | 2 seconds (cache hit) |
| CI runs on unchanged code | 18 minutes | 2 seconds (cache hit) |
Savings: On a 50-person team, remote caching saves 400+ developer hours per month.
Core Concept 2: Task Orchestration
Turborepo understands your project dependencies and runs tasks in optimal order.
Example dependency graph:
- web depends on ui-library
- mobile depends on ui-library
- ui-library depends on utils
Build order:
- Build utils (no dependencies)
- Build ui-library (depends on utils)
- Build web and mobile in parallel (both depend on ui-library)
Traditional monorepo: Builds serially (utils, ui-library, web, mobile) taking 15 minutes.
Turborepo: Builds web and mobile simultaneously after dependencies complete, taking 9 minutes (40% faster).
Core Concept 3: Incremental Builds
Turborepo only rebuilds what changed.
Scenario: You modify mobile app (nothing else).
Turborepo behavior:
- Skip building utils (unchanged, use cache)
- Skip building ui-library (unchanged, use cache)
- Skip building web (unchanged, use cache)
- Build only mobile (2 minutes)
Traditional approach: Rebuild everything (15 minutes).
Improvement: 87% faster.
Real-World Implementation: Enterprise SaaS Company
Client profile:
- 80 engineers across 5 teams
- 25 applications (web apps, mobile apps, microservices)
- 40 shared packages (component library, utilities, API clients)
- Polyrepo structure (65 separate repositories)
Problems before Turborepo:
Developer experience:
- 3-4 hours per week managing dependency updates
- 45-minute average CI time blocking PRs
- Inconsistent tooling causing onboarding delays
Business impact:
- Feature velocity decreasing (shipping 30% fewer features than 12 months prior)
- Developer satisfaction dropping (40% considering leaving due to tooling frustration)
- Cross-team collaboration difficult (shared code changes required coordinating 5-8 repos)
Migration to Turborepo Monorepo
Phase 1: Planning and Structure (2 weeks)
Designed monorepo structure:
enterprise-monorepo/
apps/
customer-portal/
merchant-dashboard/
admin-tools/
mobile-ios/
mobile-android/
packages/
ui-components/
api-client/
utils/
types/
services/
api-gateway/
auth-service/
payment-service/
notification-service/
Phase 2: Migration (6 weeks)
Migrated repositories incrementally:
- Week 1-2: Core shared packages
- Week 3-4: Customer-facing apps
- Week 5-6: Internal tools and services
Used automation scripts to preserve Git history during migration.
Phase 3: Turborepo Configuration (2 weeks)
Configured Turborepo pipeline:
turbo.json:
{
“pipeline”: {
“build”: {
“dependsOn”: [“^build”],
“outputs”: [“dist/**”]
},
“test”: {
“dependsOn”: [“build”],
“outputs”: [“coverage/**”]
},
“lint”: {},
“deploy”: {
“dependsOn”: [“build”, “test”, “lint”]
}
}
}
This configuration tells Turborepo:
- build tasks depend on dependencies being built first
- test tasks depend on local build completing
- lint can run independently
- deploy requires build, test, and lint completion
Phase 4: Remote Caching Setup (1 week)
Configured Vercel Remote Cache (could also use custom storage like AWS S3):
- Developers authenticate with cache
- CI/CD authenticates with cache
- All build/test outputs cached remotely
Results After 6 Months
Build Performance:
| Metric | Before (Polyrepo) | After (Turborepo) | Improvement |
| Local build time | 12 minutes | 2 minutes (90% cache hit) | 83% faster |
| CI time (unchanged code) | 45 minutes | 3 minutes (cache hit) | 93% faster |
| CI time (changed code) | 45 minutes | 12 minutes (parallel + incremental) | 73% faster |
| Developer wait time/week | 6 hours | 1.5 hours | 75% reduction |
Developer Productivity:
| Metric | Before | After | Improvement |
| Cross-repo changes (time) | 4 hours | 30 minutes | 87% faster |
| Dependency updates (time) | 3 hours | 20 minutes | 89% faster |
| Onboarding new developers | 5 days | 1 day | 80% faster |
| Features shipped per sprint | 12 | 19 | 58% increase |
Cost Savings:
- CI compute costs: $8,200/month reduced to $2,400/month (71% reduction)
- Developer time saved: 360 hours/month (equivalent to 2 full-time engineers)
- Value: $72,000/month in productivity gains
ROI: Migration cost $180K (10 weeks with 2-person team). Monthly savings $72K. Payback period: 2.5 months.
Turborepo Configuration Best Practices
1. Pipeline Definition
Structure your pipeline to maximize parallelization:
Good pipeline (parallel where possible):
{
“pipeline”: {
“build”: {
“dependsOn”: [“^build”],
“outputs”: [“dist/**”, “.next/**”]
},
“test”: {
“dependsOn”: [“build”]
},
“lint”: {},
“type-check”: {}
}
}
lint and type-check run in parallel because they don’t depend on each other.
Bad pipeline (unnecessary serialization):
{
“pipeline”: {
“build”: {
“dependsOn”: [“^build”, “lint”, “type-check”]
}
}
}
This forces lint and type-check to complete before build starts, even though they’re independent.
2. Cache Configuration
Specify what files affect task outputs:
{
“pipeline”: {
“build”: {
“dependsOn”: [“^build”],
“inputs”: [“src/**”, “package.json”, “tsconfig.json”],
“outputs”: [“dist/**”]
}
}
}
Turborepo only invalidates cache when inputs change. Changing README.md doesn’t trigger rebuild.
3. Remote Cache Strategy
For teams under 50 developers: Vercel Remote Cache (free tier sufficient)
For larger teams: Self-hosted cache (AWS S3, Google Cloud Storage)
Setup with AWS S3:
# Configure environment variables
TURBO_API=https://your-cache-endpoint
TURBO_TOKEN=your-auth-token
TURBO_TEAM=your-team-id
Cache hit rate target: 80%+ (means 80% of builds use cache instead of rebuilding)
4. Workspace Organization
Apps vs Packages:
- apps/: Deployable applications (websites, mobile apps, services)
- packages/: Shared libraries (not deployed independently)
Internal packages naming: Use @company-name/package-name to distinguish internal packages from external dependencies.
// apps/web/package.json
{
“dependencies”: {
“@company/ui-components”: “*”,
“@company/utils”: “*”,
“react”: “^18.2.0”
}
}
The * version means “use workspace version” (always latest local code).
When Turborepo Makes Sense
Ideal Candidates
- Multiple related applications (web, mobile, admin sharing code)
- 10+ developers (small teams may not justify setup complexity)
- Shared component libraries used across apps
- Frequent cross-project changes (API + frontend updates together)
- Microservices architecture (many services with shared types/utilities)
- CI taking 20+ minutes without caching
Example organizations:
- SaaS companies with customer app, merchant dashboard, admin tools
- eCommerce platforms with storefront, admin, mobile apps, backend services
- Fintech companies with web app, mobile apps, API gateway, payment services
- Agencies managing multiple client projects with shared component library
Not a Good Fit
- Completely unrelated projects (consulting firm with 20 different client apps)
- Very small teams (1-3 developers) (overhead not worth it)
- Projects using different tech stacks (Python backend + React frontend + mobile apps in different languages)
- Strong organizational boundaries (separate companies, strict IP separation)
- CI already fast (under 5 minutes) (optimization not needed)
Alternative Solutions
Nx (by Nrwl)
Similarities to Turborepo:
- Monorepo build system
- Remote caching
- Task orchestration
Differences:
- More opinionated (generates code, enforces structure)
- Larger ecosystem (Nx plugins for Angular, React, Node.js)
- More complex (steeper learning curve)
- Better for Angular projects (created by Angular consulting firm)
Choose Nx if: You want opinionated structure and code generation, especially for Angular projects.
Choose Turborepo if: You want minimal overhead and flexibility.
Bazel (by Google)
What it is: Google’s internal build system, open-sourced.
Advantages:
- Extremely powerful (builds anything, any language)
- Battle-tested at massive scale (Google’s entire codebase)
Disadvantages:
- Very complex (steep learning curve)
- Requires significant DevOps investment
- Overkill for most companies
Choose Bazel if: You’re building at Google scale (100K+ files) or need polyglot builds (many languages).
Choose Turborepo if: You’re building JavaScript/TypeScript projects at normal scale.
Lerna
What it is: Original JavaScript monorepo tool (2016).
Status: Maintenance mode (community-maintained, not actively developed).
Why Turborepo is better:
- Lerna doesn’t cache (slow)
- No task orchestration (no parallelization)
- No remote caching
Verdict: Turborepo supersedes Lerna for new projects.
Migration Strategies
Strategy 1: Big Bang Migration (4-8 weeks)
Move all repositories to monorepo simultaneously.
Pros:
- Fastest time to benefits
- No maintaining two systems simultaneously
Cons:
- Risky (everything changes at once)
- Requires full team coordination
- Deployment freeze during migration
Best for: Teams under 30 developers, projects under 20 repos.
Strategy 2: Incremental Migration (3-6 months)
Migrate repos gradually while maintaining polyrepo temporarily.
Phase 1: Core shared packages Phase 2: Less critical applications Phase 3: Customer-facing applications Phase 4: Backend services
Pros:
- Lower risk (rollback if issues)
- Team learns gradually
- No deployment freeze
Cons:
- Longer time to full benefits
- Maintaining two systems (polyrepo + partial monorepo)
Best for: Teams over 50 developers, mission-critical applications.
Strategy 3: Hybrid Approach (Permanent)
Keep some repos separate, consolidate related projects.
Example:
- Monorepo 1: Customer-facing products (web, mobile, shared components)
- Monorepo 2: Backend services (microservices, shared utilities)
- Separate repos: Legacy applications, third-party integrations
Best for: Large organizations with distinct business units.
Common Pitfalls and Solutions
Pitfall 1: Not Configuring Cache Properly
Problem: Low cache hit rates (under 50%) mean builds still slow.
Causes:
- Non-deterministic builds (outputs differ between runs)
- Missing cache inputs (not specifying which files matter)
- Too aggressive cache outputs (caching things that shouldn’t be cached)
Solution:
- Ensure builds are reproducible (same inputs = same outputs)
- Configure inputs explicitly in turbo.json
- Regularly monitor cache hit rates (Turborepo provides analytics)
Pitfall 2: Over-Shared Dependencies
Problem: Changing shared package triggers rebuilding 50 apps.
Solution:
- Keep shared packages focused (multiple small packages vs one large package)
- Use dependency inversion (apps depend on interfaces, not implementations)
- Consider if code really needs to be shared (sometimes duplication is better)
Pitfall 3: Ignoring CI Optimization
Problem: Turborepo speeds up local development but CI still slow.
Solution:
- Configure remote cache in CI (don’t rebuild what’s already built)
- Use GitHub Actions cache or similar
- Split CI jobs (lint in parallel with tests)
Pitfall 4: Poor Package Boundaries
Problem: Circular dependencies between packages.
Example:
- ui-components imports from utils
- utils imports from ui-components
- Build fails due to circular dependency
Solution:
- Enforce one-way dependencies (packages depend on more primitive packages, not siblings)
- Use Turborepo’s dependency graph visualization to catch cycles
- Consider splitting packages differently
Key Takeaways
- Monorepos with Turborepo deliver 70-85% faster builds through intelligent caching and parallelization
- Remote caching is the killer feature saving 400+ developer hours monthly for 50-person teams
- Polyrepo causes dependency hell and duplication that compounds as codebases grow
- Basic monorepos without tooling are too slow (45-minute CI times kill productivity)
- Turborepo simpler than alternatives (Nx more opinionated, Bazel more complex)
- ROI positive within 3-4 months for teams of 20+ developers
- Not suitable for all organizations (small teams, unrelated projects better in polyrepo)
How Askan Technologies Implements Turborepo
We’ve migrated 15+ enterprise organizations from polyrepo to Turborepo monorepo, reducing build times 70-85% and improving developer productivity 40%.
Our Monorepo Migration Services:
- Monorepo Assessment: Analyze your repos and determine if monorepo makes sense
- Architecture Design: Structure apps, packages, and services optimally
- Migration Execution: Move repositories with Git history preservation
- Turborepo Configuration: Set up pipelines, caching, and CI/CD integration
- Team Training: Hands-on workshops for developers and DevOps
- Performance Optimization: Tune cache hit rates, parallelization, and task orchestration
Recent Turborepo Implementations:
- SaaS company (80 engineers, 25 apps): 83% faster builds, 58% more features shipped
- eCommerce platform (40 engineers, 15 apps): 73% CI time reduction, $70K monthly savings
- Fintech startup (25 engineers, 12 services): 89% faster dependency updates
We deliver monorepo solutions with our 98% on-time delivery rate and 30-day free support guarantee.
Final Thoughts
The monorepo vs polyrepo debate isn’t binary. It’s about matching code organization strategy to team size, project relationships, and collaboration patterns.
For enterprises with 10+ related applications and 20+ developers, monorepo with Turborepo is the clear winner. The combination of shared code, atomic changes, and intelligent caching delivers productivity gains that compound every sprint.
For smaller teams or unrelated projects, polyrepo remains simpler and sufficient.
The companies succeeding with monorepo in 2026 are those that invested in proper tooling (Turborepo, Nx, or Bazel) instead of suffering with basic monorepo approaches that sacrifice speed for shared code.
Start by analyzing your current pain points. If you’re spending 3+ hours per week on dependency updates or 45+ minutes waiting for CI, you’re a strong candidate for Turborepo migration.
The future of enterprise codebases is monorepo. The question is whether you optimize now or wait until coordination costs become unbearable.
Most popular pages
Security as Code: Embedding AppSec Into CI/CD Without Slowing Releases
There is a particular kind of friction that security teams and engineering teams share without ever quite resolving. Engineering wants to ship fast. Security...
Feature Flags in Production: Progressive Delivery Without the Risk
The deploy button used to mean something definitive. You shipped code, users got the new version, and if something broke you scrambled to roll...
Service Mesh Architecture: When Istio and Linkerd Are Worth the Complexity
There is a specific moment in the growth of a microservices platform when the operational questions start arriving faster than the answers. How do...


