Lab 06: Monorepo TypeScript

Time: 40 minutes | Level: Advanced | Docker: docker run -it --rm node:20-alpine sh

Build a TypeScript monorepo using npm workspaces, project references, shared type packages, declaration maps, and synchronized path aliases.


Step 1: Environment Setup

docker run -it --rm node:20-alpine sh
npm install -g typescript
mkdir monorepo && cd monorepo

💡 npm workspaces (npm 7+) link packages automatically. Combined with TypeScript project references, you get type-safe cross-package imports with incremental builds.


Step 2: Root Package and Workspace Configuration

cat > package.json << 'EOF'
{
  "name": "monorepo",
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "scripts": {
    "build": "tsc --build",
    "build:clean": "tsc --build --clean && tsc --build",
    "typecheck": "tsc --build --noEmit",
    "dev": "tsc --build --watch"
  }
}
EOF

mkdir -p packages/types/src
mkdir -p packages/utils/src
mkdir -p packages/api/src
mkdir -p packages/app/src

Root tsconfig.json (orchestrator):


Step 3: Shared Types Package

The foundation — types shared across all packages:

packages/types/src/index.ts:

packages/types/tsconfig.json:


Step 4: Utilities Package

packages/utils/src/index.ts:

packages/utils/tsconfig.json:

💡 paths aliases point to source .ts files during development. At runtime, node_modules symlinks (created by npm workspaces) provide the compiled .js files.


Step 5: API Package with Path Aliases

packages/api/src/index.ts:

packages/api/tsconfig.json:


Step 6: App Package — Consuming Everything

packages/app/src/index.ts:


Step 7: Build and Verify

💡 tsc --build --verbose shows which packages are being rebuilt. Only changed packages (and their dependents) rebuild — massive CI speedup.


Step 8: Capstone — tsc --build Demo

Full build verification:

📸 Verified Output:


Summary

Concept
Configuration
Purpose

npm workspaces

"workspaces": ["packages/*"]

Auto-link packages

Composite projects

composite: true

Enable tsc --build

Project references

"references": [...]

Dependency ordering

Declaration maps

declarationMap: true

"Go to source" in IDE

Path aliases

"paths": {"@pkg": [...]}

Import without ../..

tsc --build

CLI command

Build all in order

tsc --build --clean

CLI flag

Remove all outputs

Last updated