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
Nine letters.
Discussion
Loading…