- Published on
TypeScript Monorepo in 2026 — Turborepo, Nx, and Workspaces Compared
- Authors

- Name
- Sanjeev Sharma
- @webcoderspeed1
Introduction
TypeScript monorepos serve full-stack teams by centralizing shared code, versioning, and builds. Three approaches dominate: Turborepo for speed, Nx for intelligence, and npm/pnpm workspaces for minimalism. This post compares each for teams scaling in 2026.
Monorepo Benefits for Full-Stack TS Teams
Why monorepos matter:
- Shared types: Single source of truth for API contracts, database schemas
- Code reuse: Database utilities, validation schemas across services
- Unified CI/CD: Single test, build, and deploy pipeline
- Atomic commits: API and client updates happen together
- Dependency management: One
package-lock.jsonfor the entire project
// packages/shared/src/types.ts
export interface User {
id: number;
email: string;
name: string;
createdAt: Date;
}
// packages/api/src/handlers.ts
import { User } from '@repo/shared/types';
export async function getUser(id: number): Promise<User> {
// API handler
}
// packages/web/src/hooks.ts
import { User } from '@repo/shared/types';
import { useQuery } from '@tanstack/react-query';
export function useUser(id: number) {
return useQuery<User>({
queryKey: ['user', id],
queryFn: () => getUser(id),
});
}
Changes to shared types propagate instantly; TypeScript catches breaking changes at compile time.
Turborepo: Remote Caching and Pipeline Config
Turborepo focuses on speed and remote caching. It's ideal for CI/CD pipelines and distributed teams.
{
"turbo": {
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"],
"cache": true
},
"test": {
"dependsOn": ["^build"],
"outputs": ["coverage/**"],
"cache": true,
"inputs": ["src/**", "test/**"]
},
"lint": {
"outputs": [],
"cache": true
},
"dev": {
"cache": false,
"persistent": true
}
},
"globalDependencies": ["tsconfig.json", ".eslintrc.json"]
}
}
Turborepo analyzes the dependency graph and runs tasks in parallel. Remote caching stores outputs in Vercel or self-hosted S3, speeding up CI/CD by 10-100x.
# Local build (uses cache)
pnpm turbo build --filter=@repo/api
# CI with remote cache
turbo build \
--api="https://cache.vercel.com" \
--token="$TURBO_TOKEN" \
--team="my-team"
Nx: Intelligent Caching and Affected Commands
Nx tracks project dependencies and enables running only affected tasks:
{
"nx": {
"nxCloudUrl": "https://my-nx-cloud.com"
},
"projects": {
"@repo/api": {
"projectType": "application",
"sourceRoot": "packages/api/src",
"targets": {
"build": {
"executor": "@nx/esbuild:esbuild",
"options": {
"outputPath": "dist",
"main": "packages/api/src/index.ts"
},
"cache": true
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/packages/api"],
"cache": true
}
}
}
}
}
Nx's killer feature is affected commands. After a commit, run only tests for changed packages:
# Run tests for only the packages you modified
nx affected --targets=test
# Run build for modified packages and their dependents
nx affected --targets=build
# Visualize dependency graph
nx graph --file=graph.html
Nx is more opinionated than Turborepo; it enforces project structure and provides generators.
PNPM/Yarn/npm Workspaces Comparison
All three support workspaces. pnpm is fastest due to content-addressable storage.
{
"name": "monorepo",
"version": "1.0.0",
"workspaces": [
"packages/*",
"services/*"
]
}
pnpm (recommended):
- Fastest installation (hard links)
- Strictest dependency management (explicit peer dependencies)
- Smallest
node_modulesfootprint - Native monorepo support
Yarn (legacy):
- Good for large monorepos (Yarn 3 + Yarn workspaces)
- Slower than pnpm
- Good lock file format
npm:
- Built-in workspaces (npm 7+)
- Adequate for small monorepos
- Slowest of the three
# With pnpm
pnpm install # Links all packages
pnpm --filter @repo/api run build
pnpm add -D typescript -w # Add to root
# With Yarn
yarn install
yarn workspace @repo/api run build
yarn add -D typescript --ignore-workspace-root-check
# With npm
npm install
npm run -w @repo/api build
npm install -D typescript -w
- Monorepo Benefits for Full-Stack TS Teams
- Turborepo: Remote Caching and Pipeline Config
- Nx: Intelligent Caching and Affected Commands
- PNPM/Yarn/npm Workspaces Comparison
- Shared TypeScript Configs
- Shared ESLint and Prettier Configs
- Internal Package Patterns
- Building Publishable Packages
- CI Pipeline Design for Monorepos
- Choosing Between Turborepo and Nx in 2026
- Checklist
- Conclusion
Shared TypeScript Configs
Create a root tsconfig.json that all packages extend:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"lib": ["ES2022"],
"skipLibCheck": true,
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"declaration": true,
"sourceMap": true,
"outDir": "./dist",
"baseUrl": ".",
"paths": {
"@repo/*": ["packages/*/src"]
}
}
}
Individual packages extend with overrides:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src"],
"exclude": ["dist", "node_modules"]
}
Shared configs ensure consistency across 10-100 packages without duplication.
Shared ESLint and Prettier Configs
Centralize linting rules in a shared package:
// packages/eslint-config/index.js
export default [
{
ignores: ['dist', 'node_modules', 'coverage'],
},
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': 'error',
},
},
];
Reference in each package:
{
"extends": ["@repo/eslint-config"]
}
Internal Package Patterns
Use scoped packages for internal libraries:
packages/
├── shared/ # @repo/shared
│ ├── types/ # Database, API types
│ ├── utils/ # Common utilities
│ └── validation/ # Zod schemas
├── db/ # @repo/db
│ └── Drizzle ORM setup, migrations
├── api/ # @repo/api
│ └── Backend service
├── web/ # @repo/web
│ └── Next.js frontend
└── cli/ # @repo/cli
└── CLI tools
Package naming pattern:
{
"name": "@repo/api",
"exports": {
".": "./dist/index.js",
"./handlers": "./dist/handlers.js"
}
}
Consumers import cleanly:
import { getUser } from '@repo/api/handlers';
import { User } from '@repo/shared/types';
import { db } from '@repo/db';
Building Publishable Packages
Some internal packages may publish to npm:
{
"name": "@your-org/validation",
"version": "1.0.0",
"exports": {
".": "./dist/index.js",
"./schemas": "./dist/schemas.js"
},
"files": ["dist"],
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build && npm run test"
}
}
Use semantic versioning and changelogs:
# Changelog
## 1.1.0 - 2026-03-15
- Add email validation schema
- Support international phone numbers
CI Pipeline Design for Monorepos
Turborepo-based CI pipeline:
name: CI
on: [push, pull_request]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for affected commands
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- run: pnpm install
- run: pnpm turbo build lint test
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
For Nx, use affected to test only changed packages:
- run: nx affected --targets=lint,test,build
Choosing Between Turborepo and Nx in 2026
| Aspect | Turborepo | Nx |
|---|---|---|
| Learning curve | Low | Moderate |
| Speed | Very fast | Fast |
| Remote caching | Excellent (Vercel) | Excellent (Nx Cloud) |
| Configuration | Minimal | Moderate |
| Generators | No | Yes (schematics) |
| IDE integration | Good | Excellent |
| CLI experience | Simple | Feature-rich |
| Best for | Teams valuing speed | Large enterprises |
Choose Turborepo if:
- Speed is paramount
- You want minimal configuration
- Team is using Vercel/AWS
Choose Nx if:
- You want code generators
- You need IDE plugins
- You have 10+ packages
- You're building a platform
Checklist
- Evaluate monorepo structure (flat vs nested)
- Choose Turborepo, Nx, or native workspaces
- Set up pnpm workspaces (
pnpm-workspace.yaml) - Create shared
tsconfig.jsonbase - Build
@repo/sharedpackage for types - Set up
@repo/dbfor database utilities - Configure ESLint + Prettier sharing
- Add Turborepo/Nx pipeline configuration
- Test CI build with remote caching
- Document internal package usage
Conclusion
TypeScript monorepos accelerate full-stack development by sharing types, dependencies, and build pipelines. Turborepo offers speed with minimal overhead; Nx provides intelligence for large teams. Combined with pnpm workspaces and shared configs, you can scale to 100+ packages while maintaining type safety and build performance.