🧩 How to Create a Reusable TypeScript Config Package in Turborepo

-how-to-create-a-reusable-typescript-config-package-in-turborepo

When working in a monorepo with multiple applications and packages, it’s easy for your TypeScript config files to become redundant, inconsistent, or just plain messy. Fortunately, if you’re using Turborepo, you can clean that up with a single, shareable TypeScript config package.

In this blog post, I’ll walk you through how to create a reusable @dtr-cli/typescript-config@dtr-cli is my project package, structure it for multiple project types (backend, frontend, Vite, Next.js etc.), and integrate it across your monorepo like a pro.

✅ This approach is especially helpful for developers maintaining multiple apps in a monorepo using tools like Turborepo, pnpm workspaces, or Yarn workspaces.

🧩 Step-by-Step: Creating the @dtr-cli/typescript-config Package

1. Create a Package Folder

Inside your packages/ folder, create a new directory called typescript-config.

mkdir -p packages/typescript-config && cd packages/typescript-config
npm init -y

2. Update the package.json with a proper name and export map:

{
  "name": "@dtr-cli/typescript-config",
  "version": "0.0.1",
  "description": "Shared Typescript configuration for @dtr-cli",
  "license": "ISC",
  "author": "Saiful Islam ",
  "exports": {
    "./base-tsconfig.json": "./base-tsconfig.json",
    "./backend-tsconfig.json": "./backend-tsconfig.json",
    "./react-tsconfig.json": "./react-tsconfig.json",
    "./vite-node-tsconfig.json": "./vite-node-tsconfig.json"
  },
  "files": [
    "base-tsconfig.json",
    "backend-tsconfig.json",
    "react-tsconfig.json",
    "vite-node-tsconfig.json"
  ],
  "devDependencies": {
    "@types/node": "^22.15.15"
  }
}

3. Create Base and Extended Configs

Create these four config files inside your package:

base-tsconfig.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Base",
  "compilerOptions": {
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,
    "esModuleInterop": true,
    "incremental": false,
    "sourceMap": false,
    "typeRoots": ["./node_modules/@types"]
  }
}

react-tsconfig.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "./base-tsconfig.json",
  "display": "React Library",
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx"
  }
}

vite-node-tsconfig.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "./base-tsconfig.json",
  "display": "Vite Node",
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2023"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true
  }
}

🔌 Installing the Config Package

To use your shared config package in any app inside your monorepo, add it to the app’s package.json:

"devDependencies": {
  "@dtr-cli/typescript-config": "workspace:*"
}

🛠️ How to Use the Configs

Backend App (apps/backend/tsconfig.json)

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@dtr-cli/typescript-config/backend-tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist",
    "typeRoots": ["./node_modules/@types", "./src/types"]
  },
  "include": ["./src/**/*.ts"],
  "exclude": ["node_modules", "dist"]
}

Vite app (tsconfig.app.json)

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@dtr-cli/tsconfig-config/react-tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo"
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist", "test"]
}

Vite app (tsconfig.node.json)

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@dtr-cli/tsconfig-config/vite-node.json",
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo"
  },
  "include": ["vite.config.ts"]
}

Vite app (tsconfig.json)

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

✅ Conclusion

By creating a reusable TypeScript config package in Turborepo, you:

  • Maintain consistency across all your apps.
  • DRY up repeated tsconfig.json logic.
  • Make onboarding and scaling much easier.

If you’re managing a modern monorepo setup, especially using TypeScript, Turborepo, and pnpm, this strategy will pay off quickly. It’s a small step that brings a lot of organization and clarity to your developer experience.

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
interactive-web-application-development

Interactive Web Application Development

Next Post
why-react-is-better-for-multi-page-websites?

Why React is Better for Multi-Page Websites?

Related Posts