Monorepo Setup Guide: Turborepo, pnpm, and Shared TypeScript Configs

A well-structured monorepo keeps multiple packages — frontend apps, backend services, shared libraries, and tooling configs — in a single repository with shared dependency management and build orchestration. Turborepo with pnpm is the current standard for TypeScript monorepos, offering incremental builds, remote caching, and parallel task execution.
Why Turborepo and pnpm Together
pnpm's strict dependency isolation prevents phantom dependencies — packages can only import what they explicitly declare. Turborepo builds on top of this with a caching layer that skips tasks whose inputs have not changed. Together they eliminate the two biggest pain points of monorepos: accidental cross-package imports and redundant rebuilds.
# Initialize the monorepo
mkdir my-monorepo && cd my-monorepo
pnpm init
pnpm add -g turbo
pnpm add -D typescript @types/node
Create a pnpm-workspace.yaml to define your package locations:
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
- "tooling/*"
Shared TypeScript Configuration
The config that creates the most value is a shared tsconfig base. Place it in packages/config-typescript/ and extend it from every package:
// packages/config-typescript/base.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}
Each app or package then extends the base:
// apps/web/tsconfig.json
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"plugins": [{ "name": "next" }]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}
This ensures consistent compiler behavior across every package without copy-pasting the same JSON block.
Configuring Turborepo for Optimal Caching
The turbo.json file defines task dependencies and cache configurations. The goal is to maximize cache hits while respecting dependency order:
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT_INPUTS", "src/**"],
"outputs": ["dist/**", ".next/**"],
"cache": true
},
"lint": {
"dependsOn": ["^lint"],
"cache": false
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.ts", "src/**/*.tsx"],
"outputs": []
},
"typecheck": {
"cache": true
}
}
}
The "^build" dependency means "build all dependencies of this package before building it." Turborepo uses this graph to parallelize independent packages while respecting the dependency chain.
Dependency Management Across Packages
Use pnpm's workspace protocol to reference sibling packages:
// packages/ui/package.json
{
"name": "@repo/ui",
"dependencies": {
"@repo/typescript-config": "workspace:*",
"react": "^19.0.0"
}
}
When you run pnpm install, pnpm resolves workspace:* to the local package and creates a symlink. During publishing, you can replace workspace:* with a specific version range.
Pro tip: add .npmrc with shamefully-hoist=false to maintain strict isolation. This prevents packages from accidentally accessing dependencies they did not declare.
CI Pipeline Integration
Turborepo's remote caching dramatically reduces CI times. Configure it in turbo.json with "outputLogs": "new-only" to suppress unnecessary output. Use GitHub Actions cache or Vercel Remote Caching:
- name: Cache turbo build
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
On the first push after a PR, the entire monorepo builds. On subsequent pushes, only changed packages and their dependents rebuild — often cutting CI from 15 minutes to under two.
Setting up and maintaining a monorepo requires careful configuration of package boundaries, build ordering, and CI caching. At SoniNow, we design monorepo architectures that scale with your team and product complexity.
Ready to consolidate your codebase? Get in touch with SoniNow and we will help you design a monorepo that fits your workflow.
Related Insights

CI/CD Pipeline Design: Automating Build, Test, and Deployment Workflows
A guide to designing CI/CD pipelines that automate build, test, and deployment including GitHub Actions, GitLab CI, environment strategies, and rollback patterns.

CI/CD Pipeline for Next.js: GitHub Actions to Vercel and Docker Deployments
A step-by-step guide to building CI/CD pipelines for Next.js applications using GitHub Actions including automated testing, preview deployments, Docker builds, and production rollouts.

Database Migration Strategies: Zero-Downtime Schema Changes
Learn zero-downtime database migration strategies including expand-contract patterns, online schema changes, backward-compatible migrations, and rollback planning.