Skip to main content

Module 30: Monorepo with TypeScript

Manage multiple TypeScript projects in a single repository using monorepo tools like Nx, Turborepo, and Lerna.


1. Monorepo Structure

my-monorepo/
├── packages/
│ ├── shared/
│ │ ├── src/
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── web/
│ │ ├── src/
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── api/
│ ├── src/
│ ├── package.json
│ └── tsconfig.json
├── package.json
├── tsconfig.base.json
└── turbo.json

2. Turborepo Setup

npx create-turbo@latest
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"test": {
"dependsOn": ["^build"]
},
"lint": {},
"dev": {
"cache": false
}
}
}

3. Shared Package

// packages/shared/src/types.ts
export interface User {
id: number;
name: string;
email: string;
}

export interface Post {
id: number;
title: string;
content: string;
authorId: number;
}

// packages/shared/package.json
{
"name": "@myapp/shared",
"version": "1.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsc"
}
}

4. Workspace Dependencies

// packages/web/package.json
{
"name": "@myapp/web",
"dependencies": {
"@myapp/shared": "*"
}
}

// packages/api/package.json
{
"name": "@myapp/api",
"dependencies": {
"@myapp/shared": "*"
}
}

5. Base tsconfig

// tsconfig.base.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}

6. Package-Specific tsconfig

// packages/web/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"references": [
{ "path": "../shared" }
]
}

7. Nx Monorepo

npx create-nx-workspace@latest
// nx.json
{
"tasksRunnerOptions": {
"default": {
"runner": "@nrwl/nx-cloud",
"options": {
"cacheableOperations": ["build", "lint", "test"]
}
}
}
}

8. Shared Build Scripts

// Root package.json
{
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev --parallel",
"test": "turbo run test",
"lint": "turbo run lint"
},
"workspaces": [
"packages/*"
]
}

9. Path Aliases

// tsconfig.base.json
{
"compilerOptions": {
"paths": {
"@myapp/shared": ["packages/shared/src/index"],
"@myapp/shared/*": ["packages/shared/src/*"]
}
}
}

10. Publishing Packages

// packages/shared/package.json
{
"name": "@myapp/shared",
"publishConfig": {
"access": "public"
},
"files": ["dist"],
"scripts": {
"prepublishOnly": "npm run build"
}
}

Key Takeaways

Monorepo manages multiple packages
Turborepo for fast builds
Nx for advanced features
Shared packages for code reuse
Workspace dependencies link packages


Practice Exercises

Exercise 1: Create Monorepo

Set up a monorepo with shared utilities, web app, and API.

Exercise 2: Configure CI/CD

Set up GitHub Actions for monorepo testing and deployment.


Next Steps

In Module 31, we'll explore Migration Strategies for converting JavaScript projects to TypeScript.