iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

TS in Monorepos

Once an organisation has several apps and shared libraries, a monorepo keeps everything in one place — and TypeScript's project references make cross-package types fast.

Layout

my-org/
├─ package.json                 (root — workspaces + scripts)
├─ pnpm-workspace.yaml
├─ tsconfig.base.json           (shared compiler options)
├─ tsconfig.json                (references children)
└─ packages/
   ├─ core/      (a library)
   │   ├─ src/index.ts
   │   ├─ package.json
   │   └─ tsconfig.json
   ├─ ui/       (depends on core)
   └─ web/      (depends on ui + core)

Workspaces — pnpm

pnpm-workspace.yaml
packages:
  - 'packages/*'
SHELL
pnpm add zod --filter @org/core           # install in one workspace
pnpm install                              # link them together

Workspaces — npm / yarn

package.json (root)
{
    "private": true,
    "workspaces": ["packages/*"]
}

TS project references

tsconfig.base.json
{
    "compilerOptions": {
        "target": "ES2022",
        "module": "NodeNext",
        "strict":  true,
        "composite": true,
        "declaration": true,
        "incremental": true
    }
}
packages/core/tsconfig.json
{
    "extends": "../../tsconfig.base.json",
    "compilerOptions": {
        "outDir":  "dist",
        "rootDir": "src"
    },
    "include": ["src/**/*"]
}
packages/ui/tsconfig.json
{
    "extends": "../../tsconfig.base.json",
    "compilerOptions": { "outDir": "dist", "rootDir": "src" },
    "include": ["src/**/*"],
    "references": [{ "path": "../core" }]
}
tsconfig.json (root)
{
    "files": [],
    "references": [
        { "path": "./packages/core" },
        { "path": "./packages/ui" },
        { "path": "./packages/web" }
    ]
}

Build the graph

SHELL
tsc -b                   # builds every reference in dependency order
tsc -b --watch
tsc -b --clean

Task runners

For "rebuild everything that changed" across many packages plus tests / lint / format, use:

  • Turborepo — popular, easy to configure.
  • Nx — bigger, more features (caching, graph viz, generators).
  • Moon / Lerna — alternatives.
Tip: Start without a task runner. Once tsc -b takes longer than your patience can bear, add Turborepo. Don't reach for Nx unless you actually need its graph features.

Example

Example
// pnpm workspaces or npm workspaces:
// {
//   "workspaces": ["packages/*"]
// }
//
// TS project references:
//   tsconfig.json -> {"references": [{"path": "./packages/core"}]}
//   build with:  tsc -b
console.log('Monorepos: workspaces + TS project references');
Try it Yourself »

Exercise

tsconfig flag required for project references.

" ": true

Test yourself

Q1. TS project references are turned on with…
Q2. Build all referenced projects with…
Q3. Cross-package install + linking via…

Discussion

Loading…