Repo
Docs
TypeScript

TypeScript in a monorepo

You can use TypeScript in a monorepo in one of two ways - as a linter, or as a build tool.

In this section, we'll discuss TypeScript's role as a linter. This is when you prevent TypeScript emitting files (with noEmit (opens in a new tab)) and instead use it only to check your source code's types.

Sharing tsconfig.json

We can share TypeScript config files across our repository with a clever solution. We can put our base tsconfig.json files in a single workspace, and extend them from the tsconfig.json files in our apps.

Let's imagine a workspace like this:

apps
├─ docs
│  ├─ package.json
│  ├─ tsconfig.json
├─ web
│  ├─ package.json
│  ├─ tsconfig.json
packages
├─ tsconfig
│  ├─ base.json
│  ├─ nextjs.json
│  ├─ package.json
│  ├─ react-library.json

Our tsconfig package

Inside packages/tsconfig, we have a few json files which represent different ways you might want to configure TypeScript. They each look like this:

packages/tsconfig/base.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Default",
  "compilerOptions": {
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "es2022",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "moduleResolution": "Bundler",
    "module": "ESNext",
    "noEmit": true,
    "lib": ["es2022", "dom", "dom.iterable"],
  },
  "exclude": ["node_modules"]
}

Inside package.json, we simply name our package:

packages/tsconfig/package.json
{
  "name": "tsconfig"
}

The other json files in the repository can be accessed via a simple import:

import baseJson from "tsconfig/base.json";
import nextjsJson from "tsconfig/nextjs.json";
import reactLibraryJson from "tsconfig/react-library.json";

This lets us export different config settings for different types of projects.

How to use the tsconfig package

Each app/package which uses our shared tsconfig must first specify it as a dependency:

apps/web/package.json
{
  "dependencies": {
    "tsconfig": "*"
  }
}

Then, they can extend it inside their own tsconfig.json:

apps/web/tsconfig.json
{
  // We extend it from here!
  "extends": "tsconfig/nextjs.json",
 
  // You can specify your own include/exclude
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Summary

This setup ships by default when you create a new monorepo with npx create-turbo@latest. You can also look at our basic example (opens in a new tab) to see a working version.

Running tasks

We recommend following the setup in the basics section.