How to set up a TypeScript monorepo and make Go to definition work

├── package.json
├── packages
│ ├── foo
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ ├──
│ │ └── tsconfig.json
│ └── bar
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ ├──
│ └── tsconfig.json
└── tsconfig.json
Your typical tsconfig

Path aliases

Using paths to alias our package names back to the monorepo
Each package will have one of these
Go to definition works after a fresh clone (and npm install/bootstrap)
  • omitting the compilerOptions.paths settings so that the TypeScript compiler will look in node_modules instead of in the monorepo,
  • declaring an outDir that needs to be relative to each package.
Each package has a separate config for building
Your typical package.json
  • specifying the dependencies between monorepo packages using dependencies or devDependencies (see note below) and
  • telling the tsc compiler to use our config via the -p or --project flag.
foo is not built so bar can’t find it
  1. Use lerna run to build all the packages at once and rely on it building the packages in the correct order by looking at each package’s dependencies.
  2. Use the project references feature introduced in TS 3.0.

lerna run

Project references

Using project references to automatically build the package graph
package.json with project references



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store