Skip to main content

Monorepo Configuration

If you're using a monorepo, these docs will help you figure out how to setup typed linting. If you don't want to use typed linting, then you can stop here - you don't need to do anything special.

Configurations will look different based on which setup you use:

  1. One root tsconfig.json
  2. One tsconfig.json per package (and an optional one in the root)

One root tsconfig.json

If you only have one tsconfig.json file and its include paths include all the files you'd like to lint, you can directly use it with typescript-eslint without further configuration.

If its include paths cannot include all files to be linted, we suggest creating a new config called tsconfig.eslint.json, that looks something like this:

tsconfig.eslint.json
{
// extend your base config to share compilerOptions, etc
"extends": "./tsconfig.json",
"compilerOptions": {
// ensure that nobody can accidentally use this config for a build
"noEmit": true
},
"include": [
// whatever paths you intend to lint
"src",
"test",
"tools"
]
}

Be sure to update your .eslintrc.js to point at this new config file.

One tsconfig.json per package (and an optional one in the root)

The parserOptions.project option introduced in Linting with Type Information accepts an array of relative paths. Paths may be provided as Node globs. For each file being linted, the first matching project path will be used as its backing TSConfig.

.eslintrc.js
/* eslint-env node */
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-type-checked',
],
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: true,
project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
},
plugins: ['@typescript-eslint'],
root: true,
};

Wide globs in parserOptions.project

Using wide globs ** in your parserOptions.project may degrade linting performance. Instead of globs that use ** to recursively check all folders, prefer paths that use a single * at a time.

.eslintrc.js
/* eslint-env node */
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-type-checked',
],
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.eslint.json', './**/tsconfig.json'],
project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
},
plugins: ['@typescript-eslint'],
root: true,
};

See Glob pattern in parser's option "project" slows down linting for more details.

Important note regarding large (> 10) multi-package monorepos

We've had reports that for sufficiently large and/or interdependent projects, you may run into OOMs using this approach. Our advice is to set it up and test first, as there are very few cases that trigger this OOM.

See #1192 for more information and discussion.

If you do run into an OOM, please comment on the above issue and let us know about your repo - the more information we have, the better. As an interim workaround, consider one of the following:

  • Switching to one root tsconfig.eslint.json (see One root tsconfig.json)
  • Using a shell script to only lint one package at a time, using your existing config above.

Troubleshooting

If you're having problems getting this working, please have a look at our Troubleshooting FAQ.