Configure TypeScript Project References in an Nx Workspace
In Nx 20, the @nx/js
plugin provides the ability to incrementally build projects in a monorepo using TypeScript Project References. Nx also provides a ts
preset for create-nx-workspace
that configures project references and uses workspaces
to link projects instead of TypeScript compilerOptions Paths.
The TypeScript team recommends using project references when working in a monorepo, but until now the configuration settings were difficult to maintain. Each project is required to list its own project dependencies in the references
property of the tsconfig.json
file so that TypeScript can incrementally compile projects in the correct order. In a large monorepo, maintaining those settings manually is cost prohibitive. To solve this problem, the @nx/js
plugin registers a sync generator to automatically update the references based on Nx's project graph before any TypeScript build
task is executed.
Create a New Nx Workspace Using Project References
We anticipate that this style of compiling projects will eventually become the default, but currently it will only be enabled for repositories configured in a specific way. Existing workspaces will continue to function as usual and there is no migration path yet. You can generate a new repository with these settings by using the --preset=ts
flag of the create-nx-workspace
command.
❯
npx create-nx-workspace --preset=ts
To generate an empty Nx workspace that links projects with the compilerOptions.paths
property and does not use project references, use create-nx-workspace --preset=apps
This will generate an empty repository that is configured to use TypeScript project references. To see the new functionality in action, create some TypeScript projects and make sure to use the tsc
bundler option.
❯
nx g @nx/js:lib packages/cart --bundler=tsc
❯
nx g @nx/js:lib packages/utils --bundler=tsc
These generators will detect that your repository is configured to use project references and update the configuration accordingly. If these generators were executed in an Nx repository that used compilerOptions.paths
, they would update that setting instead.
To make cart
depend on utils
, update packages/cart/package.json
like this:
1{
2 "dependencies": {
3 "utils": "*"
4 }
5}
6
Now if you run nx build cart
or directly run nx sync
, the packages/cart/tsconfig.json
file will have its references updated for you.
Project Reference Configuration Files
Nx expects the following configuration settings to be in place in order to use TypeScript project references to build projects. Most of this configuration is set up and maintained for you automatically by Nx.
Identify projects in the workspaces
property in the root package.json
file.
1{
2 "workspaces": ["packages/*"]
3}
4
The root tsconfig.base.json
should contain a compilerOptions
property and no other properties. compilerOptions.composite
and compilerOptions.declaration
should be set to true
. compilerOptions.paths
should not be set.
1{
2 "compilerOptions": {
3 // Required compiler options
4 "composite": true,
5 "declaration": true
6 // Other options...
7 }
8}
9
The root tsconfig.json
file should extend tsconfig.base.json
and not include any files. It needs to have references
for every project in the repository so that editor tooling works correctly.
1{
2 "extends": "./tsconfig.base.json",
3 "files": [], // intentionally empty
4 "references": [
5 // UPDATED BY PROJECT GENERATORS
6 // All projects in the repository
7 ]
8}
9
Each project's tsconfig.json
file should extend the tsconfig.base.json
file and list references
to the project's dependencies.
1{
2 "extends": "../../tsconfig.base.json",
3 "files": [], // intentionally empty
4 "references": [
5 // UPDATED BY NX SYNC
6 // All project dependencies
7 {
8 "path": "../utils"
9 },
10 // This project's other tsconfig.*.json files
11 {
12 "path": "./tsconfig.lib.json"
13 },
14 {
15 "path": "./tsconfig.spec.json"
16 }
17 ]
18}
19
Each project's tsconfig.lib.json
file extends the project's tsconfig.json
file and adds references
to the tsconfig.lib.json
files of project dependencies.
1{
2 "extends": "./tsconfig.json",
3 "compilerOptions": {
4 // Any overrides
5 },
6 "include": ["src/**/*.ts"],
7 "exclude": [
8 // exclude config and test files
9 ],
10 "references": [
11 // UPDATED BY NX SYNC
12 // tsconfig.lib.json files for project dependencies
13 {
14 "path": "../utils/tsconfig.lib.json"
15 }
16 ]
17}
18
The project's tsconfig.spec.json
does not need to reference project dependencies.
1{
2 "extends": "./tsconfig.json",
3 "compilerOptions": {
4 // Any overrides
5 },
6 "include": [
7 // test files
8 ],
9 "references": [
10 // tsconfig.lib.json for this project
11 {
12 "path": "./tsconfig.lib.json"
13 }
14 ]
15}
16