tsconfig.json
tsconfig.json tells TypeScript how to check and compile your project. It looks intimidating, but a handful of options matter for 95% of projects.
On this page · 5 min · Advanced
On this page
- Learning objectives
- Explanation
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Advanced
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Read and edit a tsconfig.json
- Choose target, module and lib
- Set up input and output folders
- Pick sensible settings for apps vs libraries
- Extend a shared base config
Explanation#
target: which JavaScript version to output (ES2022 is a safe modern choice). lib: which built-in APIs exist (e.g. DOM for browsers).
module and moduleResolution: how imports work. For bundled apps (Vite) use "ESNext" + "bundler". For Node.js use "NodeNext" for both.
include, rootDir and outDir: which files to check and where to write output. With a bundler, set noEmit: true — the bundler emits the JavaScript.
strict: true enables all the strict checks — always on for new projects. Extra safety: noUncheckedIndexedAccess, noImplicitOverride, noUnusedLocals.
Other useful options: sourceMap (debug original .ts), paths (import aliases), esModuleInterop, skipLibCheck (faster builds), extends (share a base config).
Code example: A modern tsconfig for a Vite / React app#
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noEmit": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
},
"include": ["src"]
}
TypeScript checks every file in src/ with strict rules and modern browser APIs. Vite handles the actual compilation, so tsc only type-checks (noEmit).
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- target ES2022 outputs modern syntax that all current browsers support.
- lib includes DOM so document and window are typed.
- ESNext + bundler matches how Vite resolves imports; jsx enables React’s JSX transform.
- strict and the extra flags catch the most bugs.
- noEmit because Vite builds the files; isolatedModules and verbatimModuleSyntax keep code compatible with fast single-file compilers.
- paths defines the @/ alias; include limits checking to src/.
Real-world use case#
For a Node.js API you would instead use "module": "NodeNext", "moduleResolution": "NodeNext", "outDir": "dist", "rootDir": "src" and no DOM lib.
Common mistakes#
Including DOM makes window and document look available in server code. Leave DOM out for Node.
module: "CommonJS" with moduleResolution: "bundler" or other mixes cause confusing import errors. Use the pairs above.
Enabling strict on a big project reveals hundreds of errors at once. Start strict from day one.
Best practices#
- Always enable strict
- Use noEmit when a bundler compiles your code
- Use NodeNext for Node.js projects
- Share settings across packages with "extends"
- Run tsc --noEmit in CI
Remember this#
target = which JS comes out. lib = which APIs exist. module = how imports work.
Bundler app: ESNext + bundler + noEmit. Node: NodeNext + outDir.
strict: true — non-negotiable.
Practice exercise#
Your task: Write a tsconfig.json for a Node.js API that compiles src/ to dist/ with strict checks and source maps.
Need a hint?
Show solution
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"rootDir": "src",
"outDir": "dist",
"strict": true,
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src"]
}
Mini quiz#
Which option stops tsc from writing JavaScript files?
Want more? Practise all TypeScript MCQs · TypeScript interview questions
My notes#
Saved in this browser.