# Setup with Turborepo

Execute the following steps to set up ESLint for a monorepo solution managed with Turborepo 👇

# Setup the workspace

# Install the packages

Open a terminal at the root of the solution's workspace (the root of the repository) and install the following packages:

pnpm add -D @workleap/eslint-plugin eslint typescript @typescript-eslint/parser turbo

# Configure Turborepo

First, create a configuration file named turbo.json at the root of the solution's workspace:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json
├── .eslintrc.json

Then, open the newly created file and copy/paste the following content:

turbo.json
{
    "$schema": "https://turbo.build/schema.json",
    "ui": "tui",
    "tasks": {
        "lint": {
            "dependsOn": ["eslint"]
        },
        "//#eslint": {
            "outputs": ["node_modules/.cache/eslint"]
        },
        "eslint": {
            "outputs": ["node_modules/.cache/eslint"]
        }
    }
}

The //#eslint task will execute the eslint script at the root of the solution's workspace and the eslint task will execute the eslint script for every project of the solution's workspace.

# Configure ESLint

Next, let's configure ESLint. Create a configuration file named .eslintrc.json at the root of the solution's workspace:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json
├── .eslintrc.json

Then, open the newly created file and extend the default configuration with the monorepo-workspace shared configurations:

.eslintrc.json
{
    "$schema": "https://json.schemastore.org/eslintrc",
    "root": true,
    "extends": "plugin:@workleap/monorepo-workspace"
}

# .eslintignore

ESLint can be configured to ignore certain files and directories while linting by specifying one or more glob patterns.

To do so, first, create a .eslintignore file at the root of the solution's workspace:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json
├── .eslintrc.json
├── .eslintignore

Then, open the newly created file and paste the following ignore rules:

.eslintignore
**/dist/*
node_modules
__snapshots__
storybook-static
pnpm-lock.yaml
package-lock.json
*.md
!.storybook

# Configure indent style

ESLint offers built-in rules for configuring the indentation style of a codebase. However, there's a catch: when VS Code auto-formatting feature is enabled, it might conflict with the configured indentation rules if they are set differently.

To guarantee a consistent indentation, we recommend using EditorConfig on the consumer side. With EditorConfig, the indent style can be configured in a single file and be applied consistently across various formatting tools, including ESlint and VS Code.

First, create a .editorconfig file at the root of the solution's workspace:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json
├── .eslintrc.json
├── .eslintignore
├── .editorconfig

Then, open the newly created file and paste the following configuration:

.editorconfig
root = true

[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

[*.md]
trim_trailing_whitespace = false

# Add CLI scripts

Finally, add the lint and eslint scripts to your solution's workspace package.json file.

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json    <------- (this one!)
├── turbo.json
├── .eslintrc.json
├── .eslintignore
├── .editorconfig

The lint script will execute the lint task and it's dependencies configured earlier in the turbo.json file:

package.json
{
    "lint": "turbo run lint --continue"
}

The eslint script will lint the root of the solution's workspace:

package.json
{
    "eslint": "eslint . --ignore-pattern packages --max-warnings=-0 --cache --cache-location node_modules/.cache/eslint"
}

# Setup a project

# Install the packages

Open a terminal at the root of the project (packages/pkg-1 for this example) and install the following packages:

pnpm add -D @workleap/eslint-plugin

# Configure ESLint

First, create a configuration file named .eslintrc.json at the root of the project:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├────── .eslintrc.json
├── package.json
├── .eslintrc.json
├── .eslintignore
├── .editorconfig

Then, open the newly created file and extend the default configuration with one of the shared configurations provided by @workleap/eslint-plugin 👇

# web-application

For an application developed with TypeScript and React, use the following configuration:

packages/pkg-1/.eslintrc.json
{
    "$schema": "https://json.schemastore.org/eslintrc",
    "root": true,
    "extends": "plugin:@workleap/web-application"
}

# react-library

For a TypeScript library developed with React, use the following configuration:

packages/pkg-1/.eslintrc.json
{
    "$schema": "https://json.schemastore.org/eslintrc",
    "root": true,
    "extends": "plugin:@workleap/react-library"
}

# typescript-library

For a TypeScript library developed without React, use the following configuration:

packages/pkg-1/.eslintrc.json
{
    "$schema": "https://json.schemastore.org/eslintrc",
    "root": true,
    "extends": "plugin:@workleap/typescript-library"
}

# Add a CLI script

Finally, add the following eslint script to your project package.json file. This script will be executed by Turborepo:

packages/pkg-1/package.json
{
    "eslint": "eslint . --max-warnings=-0 --cache --cache-location node_modules/.cache/eslint"
}

# Custom configuration

New projects shouldn't have to customize the default configurations offered by @workleap/eslint-plugin. However, if you are in the process of migrating an existing project to use this library or encountering a challenging situation, refer to the custom configuration page to understand how to override or extend the default configurations. Remember, no locked in ❤️✌️.

# Try it 🚀

To test your new ESLint setup, open a JavaScript file, type invalid code (e.g. var x = 0;), then save. Open a terminal at the root of the solution and execute the CLI script added earlier:

pnpm lint

The terminal should output a linting error.