# Setup a monorepo

To lint a monorepo solution (multiple projects per repository), TypeScript must be setuped to lint the files at the root of the solution (the monorepo workspace) and the files of every project of the monorepo. Execute the following steps to setup TypeScript for a monorepo solution.

# Setup the workspace

# Install the packages

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

pnpm add -D @workleap/typescript-configs typescript
yarn add -D @workleap/typescript-configs typescript
npm install -D @workleap/typescript-configs typescript

# Configure TypeScript

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

workspace
├── packages
├──── app
├────── src
├──────── ...
├────── package.json
├── package.json
├── tsconfig.json

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

tsconfig.json
{
    "extends": "@workleap/typescript-configs/monorepo-workspace.json",
    "exclude": ["packages", "node_modules"]
}

If your application is using Storybook, make sure to include the .storybook folder and exclude the .storybook/storybook-static folder:

tsconfig.json
{
    "extends": "@workleap/typescript-configs/monorepo-workspace.json",
    "include": ["**/*", ".storybook/*"],
    "exclude": ["packages", "node_modules", ".storybook/storybook-static"]
}

# Add a CLI script

At times, especially when running the CI build, it's useful to lint the entire solution using a single command. To do so, add the following script to your solution's workspace package.json file:

workspace
├── packages
├──── app
├────── src
├──────── ...
├────── package.json
├── package.json    <------- (this one!)
├── tsconfig.json
package.json
{
    "lint:types": "pnpm -r --parallel --include-workspace-root exec tsc"
}

# Setup a project

# Install the package

Open a terminal at the root of the project (packages/app for this example) and install the following package:

pnpm add -D @workleap/typescript-configs typescript
yarn add -D @workleap/typescript-configs typescript
npm install -D @workleap/typescript-configs typescript

# Configure TypeScript

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

workspace
├── packages
├──── app
├────── src
├──────── ...
├────── package.json
├────── tsconfig.json
├── package.json
├── tsconfig.json

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

# web-application

For an applications developed with React, use the following configuration:

tsconfig.json
{
    "extends": ["@workleap/typescript-configs/web-application.json"],
    "exclude": ["dist", "node_modules"]
}

# library

For a library project developed with or without React, use the following configuration:

tsconfig.json
{
    "extends": ["@workleap/typescript-configs/library.json"],
    "exclude": ["dist", "node_modules"]
}

# Custom configuration

New projects shouldn't have to customize most of the default configurations offered by @workleap/typescript-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 ❤️✌️.

# Compiler paths

If any projects of your solution are referencing other projects of the monorepo workspace (e.g. "@sample/components": "workspace:*"), chances are that you'll need to define paths in their tsconfig.json file.

Given the following solution:

workspace
├── packages
├──── app
├────── src
├──────── ...
├────── package.json
├────── tsconfig.json
├──── components (@sample/components)
├────── src
├──────── index.ts
├────── package.json
├────── tsconfig.json
├──── utils (@sample/utils)
├────── src
├──────── index.ts
├────── package.json
├────── tsconfig.json
├── package.json
├── tsconfig.json

If the packages/components project is referencing the packages/utils project, and the packages/app project is referencing the packages/components project, you'll need to add the following compilerOptions.paths:

packages/app/tsconfig.json
{
    "extends": "@workleap/typescript-configs/web-application.json",
    "compilerOptions": {
        "paths": {
            "@sample/components": ["../components/index.ts"],
            "@sample/utils": ["../utils/index.ts"]
        }
    },
    "exclude": ["dist", "node_modules"]
}
packages/components/tsconfig.json
{
    "extends": "@workleap/typescript-configs/library.json",
    "compilerOptions": {
        "paths": {
            "@sample/utils": ["../utils/index.ts"]
        }
    },
    "exclude": ["dist", "node_modules"]
}

# Try it 🚀

To test your new TypeScript setup, open a TypeScript file, type invalid code (e.g. import { App } from "./App"), then wait for the IDE to flag the error. Fix the error (e.g. import { App } from "./App.tsx"), then wait for the IDE to remove the error.