DEV Community

Cover image for How to Configure tsconfig.json for Your TypeScript Project
Krunal Kanojiya
Krunal Kanojiya

Posted on

How to Configure tsconfig.json for Your TypeScript Project

TLDR

tsconfig.json is the config file for every TypeScript project. It tells the TypeScript compiler what to check and how to build your code. Run tsc --init to create one. The key options you need to know are target, module, strict, outDir, and rootDir. Always turn on strict mode. It saves you from many bugs.


What is tsconfig.json?

tsconfig.json is a file that lives at the root of your TypeScript project. It controls how TypeScript compiles your code.

When you run tsc in your terminal, TypeScript looks for this file first. It reads your settings and uses them to type-check and compile your .ts files.

Without this file, the TypeScript compiler uses its default settings. Those defaults are not always the best for your project. That is why you should always create and customize your own tsconfig.json.


How to Create tsconfig.json

You do not have to write this file by hand. TypeScript gives you a command to create one.

Step 1: Make sure TypeScript is installed.

npm install -g typescript
Enter fullscreen mode Exit fullscreen mode

Step 2: Run the init command in your project folder.

tsc --init
Enter fullscreen mode Exit fullscreen mode

This creates a tsconfig.json file with many options inside it. Most of them are commented out.

Your project folder should look like this:

my-project/
├── src/
│   └── index.ts
├── tsconfig.json
└── package.json
Enter fullscreen mode Exit fullscreen mode

The Structure of tsconfig.json

A tsconfig.json file has a few top-level keys. Here is what each one does:

Key What It Does
compilerOptions Controls how TypeScript compiles your code
include Tells TypeScript which folders or files to compile
exclude Tells TypeScript which folders or files to skip
files Lists specific files to include (rarely used)
extends Lets you inherit settings from another config file

The most important key is compilerOptions. This is where all the action happens.

Here is a basic example of the full structure:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}
Enter fullscreen mode Exit fullscreen mode

Core Compiler Options Explained

There are hundreds of compiler options. You do not need to know all of them. Here are the ones you will use in almost every project.

Option Type Default What It Does
target string ES3 Sets the JavaScript version for output
module string depends Sets how modules are handled
strict boolean false Turns on all strict type checks
outDir string none Folder where compiled JS files go
rootDir string none Root folder of your TypeScript source files
lib array depends Built-in type definitions to include
sourceMap boolean false Creates .map files for debugging
declaration boolean false Creates .d.ts type files
skipLibCheck boolean false Skips type checking of .d.ts files
esModuleInterop boolean false Allows default imports from CommonJS modules
resolveJsonModule boolean false Lets you import .json files

How to Set the target Option

The target option tells TypeScript which version of JavaScript to compile your code to.

For example, if you set target to ES5, TypeScript turns your modern arrow functions into old function expressions. If you set it to ES2020, it keeps modern syntax as-is.

Which target should you pick?

Target Use It When
ES5 You need to support very old browsers
ES6 / ES2015 Older Node.js projects
ES2017 You want async/await in the output
ES2020 Good default for most modern projects
ES2022 Best for modern Node.js (v16+)
ESNext Always use the latest JS features
{
  "compilerOptions": {
    "target": "ES2022"
  }
}
Enter fullscreen mode Exit fullscreen mode

Tip: ES2022 is a safe and modern choice for most new projects in 2025. It is stable and supported by all modern browsers and Node.js versions.


How to Set the module Option

The module option controls how TypeScript handles import and export statements in the compiled output.

This option depends on where your code will run.

module Value Use It When
CommonJS Building for Node.js
ESNext Building for modern browsers or bundlers like Vite
NodeNext Building for Node.js with native ES modules support
AMD Old browser projects (rarely used now)
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "CommonJS"
  }
}
Enter fullscreen mode Exit fullscreen mode

For most Node.js projects, use CommonJS. For browser projects with a bundler like Vite or Webpack, use ESNext.


How to Enable Strict Mode

strict is the most important option in tsconfig.json. It turns on a group of type-checking rules all at once.

When strict is true, TypeScript becomes much better at catching bugs before your code runs.

Here is what strict: true turns on for you:

Option Enabled What It Prevents
strictNullChecks Using null or undefined where a value is expected
noImplicitAny Using variables without a type
strictFunctionTypes Wrong function parameter types
strictPropertyInitialization Class properties that are never set
useUnknownInCatchVariables Unsafe use of catch error variables
{
  "compilerOptions": {
    "strict": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Always set strict: true. Starting without it and adding it later is painful. You will have a lot of errors to fix. Start strict from day one.


How to Set outDir and rootDir

These two options work together. They control where TypeScript reads your source files from and where it puts the compiled JavaScript files.

  • rootDir points to your TypeScript source folder (usually ./src)
  • outDir points to the folder where compiled files should go (usually ./dist)
{
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist"
  }
}
Enter fullscreen mode Exit fullscreen mode

After running tsc, your project will look like this:

my-project/
├── src/
│   ├── index.ts       <-- TypeScript source
│   └── utils.ts
├── dist/
│   ├── index.js       <-- Compiled JavaScript
│   └── utils.js
├── tsconfig.json
└── package.json
Enter fullscreen mode Exit fullscreen mode

Tip: Add dist to your .gitignore file. You do not need to commit compiled files to Git.


How to Configure include and exclude

These two options sit outside compilerOptions. They control which files TypeScript looks at.

include tells TypeScript which files or folders to compile:

{
  "include": ["src", "tests"]
}
Enter fullscreen mode Exit fullscreen mode

exclude tells TypeScript which files or folders to ignore:

{
  "exclude": ["node_modules", "dist", "**/*.spec.ts"]
}
Enter fullscreen mode Exit fullscreen mode

By default, TypeScript excludes node_modules automatically. But it is a good habit to list it yourself so nothing surprises you.


How to Set Up Path Aliases with paths

Path aliases let you use short import names instead of long relative paths.

Without aliases, your imports look like this:

import { formatDate } from "../../../utils/formatDate";
Enter fullscreen mode Exit fullscreen mode

With path aliases, the same import looks like this:

import { formatDate } from "@utils/formatDate";
Enter fullscreen mode Exit fullscreen mode

Here is how to set that up in tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@utils/*": ["src/utils/*"],
      "@models/*": ["src/models/*"],
      "@services/*": ["src/services/*"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Important: paths in tsconfig.json is only for TypeScript. If you use a bundler (like Webpack or Vite), you need to set up the same aliases in your bundler config too.


How to Add lib for Extra Type Definitions

The lib option tells TypeScript which built-in type definitions to include.

If you are building for browsers, you need the DOM types. If you are building for Node.js, you do not.

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "DOM", "DOM.Iterable"]
  }
}
Enter fullscreen mode Exit fullscreen mode
lib Value Includes Types For
ES2022 Modern JavaScript APIs
DOM Browser APIs like document and window
DOM.Iterable Iterating over DOM collections
ESNext The very latest JS features

For Node.js projects, skip DOM and just use ["ES2022"].


How to Enable Source Maps for Debugging

Source maps connect your compiled JavaScript back to your original TypeScript code. This makes debugging much easier in tools like VS Code and browser dev tools.

{
  "compilerOptions": {
    "sourceMap": true
  }
}
Enter fullscreen mode Exit fullscreen mode

This creates a .map file next to each compiled .js file. Debuggers use these files to show you the TypeScript line number when something breaks.


Complete tsconfig.json Templates

Here are two ready-to-use configs you can copy.

For a Node.js Project

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "CommonJS",
    "lib": ["ES2022"],
    "rootDir": "./src",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "declaration": false
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}
Enter fullscreen mode Exit fullscreen mode

For a Browser App (with a Bundler like Vite)

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "rootDir": "./src",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "moduleResolution": "Bundler",
    "resolveJsonModule": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}
Enter fullscreen mode Exit fullscreen mode

Common Mistakes to Avoid

Here are the most common tsconfig.json mistakes developers make.

  • Not enabling strict: true -- You will miss many bugs that TypeScript would have caught.
  • Wrong rootDir path -- If TypeScript cannot find your source files, it will not compile.
  • Forgetting to exclude node_modules -- TypeScript may try to compile third-party packages and throw errors.
  • Mismatched target and lib -- If your lib has features that your target does not support, you get errors.
  • Using paths without baseUrl -- Path aliases do not work unless baseUrl is also set.

Quick Reference: Most Used Options

Option Recommended Value Reason
target ES2022 Modern and stable
module CommonJS (Node) / ESNext (browser) Matches your runtime
strict true Catch more bugs at compile time
rootDir ./src Keeps source organized
outDir ./dist Keeps compiled files separate
esModuleInterop true Easier imports from npm packages
skipLibCheck true Faster builds
sourceMap true Better debugging

FAQ

Q: Do I need a tsconfig.json file?
Yes. Without it, TypeScript uses defaults that may not match your project. Always create one.

Q: Can I have more than one tsconfig.json?
Yes. Large projects often have multiple config files. You can use extends to share settings between them.

Q: What does skipLibCheck: true do?
It tells TypeScript to skip type checking inside .d.ts files from your node_modules. This speeds up compilation. It is safe to turn on for most projects.

Q: What is the difference between target and lib?
target sets the JavaScript version of your output. lib sets which built-in type definitions TypeScript knows about. They are related but separate.

Q: Should I commit tsconfig.json to Git?
Yes. Always commit tsconfig.json. It is part of your project setup. Do not commit the dist folder.

Q: Why does TypeScript say "rootDir is expected to contain all source files"?
This happens when TypeScript finds a .ts file outside your rootDir. Check if your test files or other config files are placed inside rootDir or adjust your include and rootDir settings.


What You Learned

  • tsconfig.json is the config file for TypeScript projects
  • You create it with tsc --init
  • compilerOptions controls how TypeScript compiles your code
  • Always use strict: true to catch more bugs
  • rootDir sets where your source files are and outDir sets where compiled files go
  • Use include and exclude to control which files TypeScript processes
  • Path aliases (paths) make imports cleaner

Sources: TypeScript Official Docs | Total TypeScript TSConfig Cheat Sheet

Top comments (0)