Linting in a monorepo

Linting in a monorepo can be tricky. Most of your workspaces will likely contain code that needs to be linted - so working out the most efficient way to lint them is tough.

In this guide, we'll propose a method that plays to Turborepo's strengths:

  • Running lint tasks inside the workspaces, not from root
  • Sharing as much config as possible between workspaces

Running tasks

We recommend specifying a single lint task inside your turbo.json.

turbo.json
{
  "pipeline": {
    "lint": {
      "outputs": []
    }
  }
}

Then, inside each workspace that needs to be linted, add a lint script. We'll use TypeScript as an example:

packages/*/package.json
{
  "scripts": {
    "lint": "tsc"
  }
}

This pattern has two benefits:

  • Parallelization: the lint tasks will be run concurrently, speeding them up
  • Caching: lint tasks will only be re-run on workspaces that have changed

This means you can lint your entire repo using one command:

turbo run lint

Sharing config files

Sharing configuration across a monorepo helps keep the development experience consistent. Most linters will have a system for sharing config, or extending config across different files.

So far, we've built guides for sharing config in: