
Making Sense of tsconfig
Published
The tsconfig.json
file is a crucial file in every TypeScript project, because this file configures which code files get checked and compiled by TypeScript, how those files get validated and what the output (if any) of the compilation process should be.
Unfortunately, when using tsc --init
, a newly generated tsconfig.json
file is often not configured appropriately for modern web development.
In addition, understanding all the various settings and their possible values (and effects) can be a nightmare - though the official documentation page generally does a good job at explaining most options. The problem just is, that (for historic reasons) there are many settings you’ll rarely (or never) need.
Fortunately, you often don’t need to set up the tsconfig.json
file, though. Typically, you’ll create new projects (e.g., new React, Expo, Angular projects) with help of some build tool or templating tool (e.g., Vite ). When choosing TypeScript as a language, those tools generate well-defined tsconfig.json
files for you.
A Solid Base tsconfig.json File
If you’re working in a project that doesn’t come with a pre-configured tsconfig.json
file you can consider using the following configuration as a good base:
{
"compilerOptions": {
"esModuleInterop": true, // Ensures ESM and CJS imports work together well
"skipLibCheck": true, // Ensures .d.ts files from 3rd libraries are not type-checked
"target": "ES2022", // Sets a relatively modern ECMAScript version as compilation target
"allowJs": true, // Allows importing .js files into .ts (helpful when migrating projects)
"strict": true, // Ensures strict type checking (i.e., noImplicitAny etc)
"noUncheckedIndexedAccess": true, // Adds undefined as a value when accessing by index
// "noImplicitOverride": true, // Enable this when working with classes & inheritance
"noUnusedLocals": true, // to avoid unused variables
"module": "NodeNext", // Supports both ESM & CJS modules / imports; ESNext for frontend projects
"outDir": "dist", // Store compiled files in "dist" folder
"sourceMap": true, // Enables source maps for easier debugging
"lib": ["ES2022", "DOM", "DOM.Iterable"] // Or without "dom" libs when building for Node
}
}
Below you find a short explanation of these core settings.
Core Settings
-
"target": "ES2022"
: This setting determines which JavaScript version TypeScript compiles down to. More infoES2022
is a modern version supported by recent browsers and Node.js versions. Using this setting avoids creating unnecessarily extra code during compilation.- If you need to support older browsers, consider using
ES6
or evenES5
.
-
"esModuleInterop": true
: This enables better compatibility between ECMAScript Modules (ESM, usingimport
/export
) and CommonJS modules (CJS, usingrequire()
). More info . -
"skipLibCheck": true
: This tells TypeScript not to type-check declaration (.d.ts
) files in yournode_modules
folder. In theory, different libraries could define conflicting types. With this option set totrue
, TypeScript will only check types you’re actually using, hence speeding up compilation. More info . -
"allowJs": true
: Allows you to import.js
files directly into your .ts files. This is extremely useful when gradually migrating a JavaScript project to TypeScript, or when using JavaScript libraries that don’t have type definitions. More info . -
"strict": true
: A must-have! Enables a suite of strict type-checking rules, includingnoImplicitAny
,noImplicitThis
,strictNullChecks
, and more. This catches many common errors at compile time and leads to more robust code. Highly recommended for all projects! More info . -
"noUncheckedIndexedAccess": true
: When accessing an element in an array or object by index (e.g.,myArray[2]
ormyObject['someKey']
), this setting addsundefined
to the possible return type. This forces you to handle cases where the index might be out of bounds or the key might not exist, preventing runtime errors. More info . -
"noImplicitOverride": true
: This setting is class-related. When you’re using class inheritance and overriding a parent class, setting this will make it required to use theoverride
keyword on your methods. If you accidentally introduce a method on the child class, that by name clashes with a base class’s method, the compiler will throw an error (because you didn’t addoverride
). More info . -
"noUnusedLocals": true
: Reports an error if you declare a local variable but never use it. This helps keep your code clean and avoids potential confusion. More info . -
"module": "NodeNext"
: Specifies the module system for your compiled code (i.e., how youimport
/export
statements will look like in the compiled code). More info .-
NodeNext
is a good choice for modern Node.js projects as it supports both ESM and CJS, ensuring broad compatibility. -
Consider using
ESNext
for frontend projects.
-
-
"outDir": "dist"
: Specifies the output directory for your compiled JavaScript files. More info . -
"sourceMap": true
: Generates source map files (.js.map
). Source maps allow debuggers (like the one in your browser’s developer tools) to map the compiled JavaScript code back to your original TypeScript source code, making debugging much easier. More info . -
"lib": ["ES2022", "DOM", "DOM.Iterable"]
: This setting tells TypeScript which built-in API definitions to include. Without this setting, using globally available APIs likedocument.querySelector()
will error. TypeScript will inferlib
from your chosentarget
- hence you should also be able to not setES2022
with atarget
ofES2022
. More info ."es2022"
: Includes the type definitions for standard JavaScript features up to ES2022."dom"
: Includes type definitions for the browser’s Document Object Model (DOM) APIs (e.g., document, window). Essential for web development."dom.iterable"
: Includes definitions for DOM APIs that return iterable objects (e.g.,NodeList
). If you’re not building for the browser (e.g., a Node.js backend), you can remove"DOM"
and"DOM.Iterable"
.