← Back to TypeScript Course | Chapter 26: Monorepos and Large Projects | Lesson 3 of 5

TypeScript Project References

Project references let a TypeScript project depend on other TypeScript projects. They are useful for large repositories with separate packages.

Core Concept

Project references let you split a large TypeScript codebase into smaller sub-projects, each with its own tsconfig.json, while tsc --build compiles them in dependency order and skips any sub-project whose inputs haven't changed.

Example: Core Concept

typescript
// core/tsconfig.json and app/tsconfig.json, split from one giant project
console.log("Project references split a codebase into independently built pieces");

Basic Setup

A basic setup adds "composite": true to each referenced sub-project's tsconfig.json (required for the incremental build info to be emitted) and a references array in the consuming project's tsconfig.json pointing at the paths of its dependencies.

Example: Basic Setup

typescript
// core/tsconfig.json: { "compilerOptions": { "composite": true } }
// app/tsconfig.json: { "references": [{ "path": "../core" }] }
console.log("composite: true plus references wires the two projects together");

Typed Example

A typed example: package core exports typed utilities, package app lists { "path": "../core" } in its references, and importing from core inside app resolves to core's compiled declaration files rather than re-parsing its source.

Example: Typed Example

typescript
// core exports a typed utility, app imports from "core"
// app resolves against core's compiled .d.ts, not core's raw source.
function double(x: number): number { return x * 2; }
console.log(double(5));

Project Usage

In a real project, project references turn what would be one slow monolithic tsc run into many small, independently cacheable builds — critical once a codebase grows past a few hundred files.

Example: Project Usage

typescript
// tsc --build builds only what changed, in dependency order
console.log("References turn one slow tsc run into many small cacheable ones");

Best Practices

Always pair project references with "composite": true and run builds through tsc --build (not plain tsc), since a composite project's declaration output is what makes the whole reference graph actually work.

Example: Best Practices

typescript
// Always run: tsc --build   (not plain tsc)
console.log("composite + tsc --build is what makes the reference graph work");
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.