Setup with Turborepo

Execute the following steps to set up Stylelint 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/stylelint-configs stylelint prettier 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

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

turbo.json
{
    "$schema": "https://turbo.build/schema.json",
    "ui": "tui",
    "globalDependencies": [".prettierrc.json5"],
    "tasks": {
        "lint": {
            "dependsOn": ["stylelint"]
        },
        "stylelint": {
            "outputs": ["node_modules/.cache/stylelint"]
        }
    }
}

The stylelint task will execute the stylelint script for every project of the solution's workspace. The root .prettierrc.json5 file (see below) configures Stylelint in every project: as a global dependency, a change to it runs Stylelint again everywhere instead of replaying cached results.

Configure Stylelint

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

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

Then, open the newly created file and extend the default configuration with the shared configurations provided by @workleap/stylelint-configs:

.stylelintrc.json
{
    "$schema": "https://json.schemastore.org/stylelintrc",
    "extends": "@workleap/stylelint-configs"
}

.stylelintignore

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

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

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

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

.stylelintignore
**/dist/*
node_modules
storybook-static
!.storybook

.prettierrc.json5

@workleap/stylelint-configs formats CSS files with Prettier, through stylelint-prettier, while oxfmt formats the rest of the code. Prettier doesn't read oxfmt's configuration, so give it a CSS-scoped configuration that uses the same options.

First, create a .prettierrc.json5 file at the root of the solution's workspace. Prettier looks for it in the parent folders, so it applies to every project:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json
├── turbo.json
├── .stylelintrc.json
├── .stylelintignore
├── .prettierrc.json5

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

.prettierrc.json5
// stylelint-prettier formats CSS with Prettier, which doesn't read oxfmt.config.ts.
// Keep these options in sync with oxfmt.config.ts.
{
    $schema: "https://json.schemastore.org/prettierrc",
    overrides: [
        {
            files: "*.css",
            options: {
                printWidth: 150,
                tabWidth: 4,
                useTabs: false,
                singleQuote: false,
                endOfLine: "lf"
            }
        }
    ]
}

Configure the indent style

Prettier 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 Prettier 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
├── .stylelintrc.json
├── .stylelintignore
├── .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

[*.{yml,yaml}]
indent_size = 2

Add a CLI script

Finally, add the following script to your solution's workspace package.json file:

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├── package.json    <------- (this one!)
├── turbo.json
├── .stylelintrc.json
├── .stylelintignore
├── .editorconfig
package.json
{
    "lint": "turbo run lint --continue"
}

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 package:

pnpm add -D @workleap/stylelint-configs

Configure Stylelint

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

workspace
├── packages
├──── pkg-1
├────── src
├──────── ...
├────── package.json
├────── .stylelintrc.json
├── package.json
├── .stylelintrc.json
├── .stylelintignore
├── .editorconfig

Then, open the newly created file and extend the default configuration with the shared configurations provided by @workleap/stylelint-configs:

packages/pkg-1/.stylelintrc.json
{
    "$schema": "https://json.schemastore.org/stylelintrc",
    "extends": "@workleap/stylelint-configs"
}

Add a CLI script

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

packages/pkg-1/package.json
{
    "stylelint": "stylelint \"**/*.css\" --allow-empty-input --cache --cache-location node_modules/.cache/stylelint --max-warnings=0"
}

Custom configuration

New projects shouldn't have to customize the default configurations offered by @workleap/stylelint-configs. 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 setup, open a CSS file, type invalid code (e.g. color: #fff), 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.