tsconfig generator
Generate a tsconfig.json for Node ESM, Node CJS, the browser, a library, React, Vue or Astro, with target, strict, path aliases and include/exclude controls plus a one-line explanation for every key option.
Runs in your browserEvery computation happens in your browser — your data never leaves this device.
Runtime
Preview
{
"compilerOptions": {
"target": "ES2022",
"lib": [
"ES2022"
],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"types": [
"node"
],
"strict": true,
"noEmit": false,
"outDir": "dist",
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"src"
],
"exclude": [
"node_modules",
"dist"
]
}
target: ES2022target ES2022: class fields, top-level await and at() pass through, supported by Node 18 and current browsers.
lib: ES2022lib decides which global APIs exist: Node projects skip DOM, front-end projects need DOM and DOM.Iterable.
module: NodeNextmodule NodeNext: Node picks ESM or CJS from package.json type, and relative imports must carry their extension.
moduleResolution: NodeNextmoduleResolution NodeNext follows module and uses Node resolution rules for packages and extensions.
types: nodetypes limits which global type packages are loaded automatically, avoiding conflicts and slowdowns from all of @types.
strict: truestrict enables every strict check at once (strictNullChecks, noImplicitAny and friends) — keep it on for new projects.
noEmit: falsenoEmit means type check only: true when a bundler owns the output, false for Node and library builds.
isolatedModules: trueisolatedModules requires every file to be transpilable on its own, which rules out type-only imports that vanish.
verbatimModuleSyntax: trueverbatimModuleSyntax forces import type to be written separately, so TypeScript never rewrites module syntax.
include: srcinclude decides which files are compiled — listing only source directories avoids recompiling build output.
exclude: node_modules, distexclude skips directories entirely; node_modules and build output almost always belong here.
This is a standalone config: to extend a base config switch to extends, but delete the options you no longer override so the two files do not fight each other.
What this tool does
- Write a tsconfig.json for a new project without guessing how module and moduleResolution should be paired — pick the runtime and the config is ready.
- Migrate a legacy project from CommonJS to ESM: switch to Node (ESM) to see exactly what NodeNext expects before moving code over.
- Ship a library with types: the Library environment already combines declaration, declarationMap and outDir.
- Debug a type error by reading the option notes: they tell you whether target, lib or a strict flag is behind it.
Example
Input
Environment Node (ESM); target left on the environment default; strict on; include src; exclude node_modules, dist
Output
{
"compilerOptions": {
"target": "ES2022",
"lib": [
"ES2022"
],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"types": [
"node"
],
"strict": true,
"noEmit": false,
"outDir": "dist",
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"src"
],
"exclude": [
"node_modules",
"dist"
]
}
target follows the environment by default (ES2022 here); enabling path aliases also adds baseUrl: "." plus paths, and every key option gets a one-line explanation below.
Frequently asked questions
What is the difference between module and moduleResolution?
module picks the emitted module format (ESM, CommonJS or untouched), while moduleResolution decides how TypeScript finds files and packages. They must match: NodeNext with NodeNext for Node, ESNext with Bundler for a front-end bundler, CommonJS with node10 for legacy projects.
Why does the browser environment set noEmit?
Type checking for front-end code is usually tsc --noEmit, while Vite, webpack or Astro produces the bundle. If TypeScript also emitted files the output would be duplicated or overwritten, so the browser, React, Vue and Astro presets keep noEmit: true.
Should lib include DOM?
It depends on where the code runs. Adding DOM to a Node project lets document and window pass type checking only to fail at runtime; leaving it out of a front-end project means document is unknown. The presets already choose per environment.
Is noUncheckedIndexedAccess too strict?
It makes obj[key] and arr[i] possibly undefined, forcing you to handle out-of-range access. That is valuable for public libraries and data processing, but it flags a lot of existing code — enable it from day one on new projects and evaluate separately for old ones.
Can I use the generated config as-is?
Save it as tsconfig.json in the project root and you are done. To share a company base config, either move compilerOptions into the extended file or turn this config into an extends file and delete the duplicated options so the two files cannot fight.
Keywords:tsconfigtsconfig.jsontsconfig 生成typescript 配置moduleResolutionNodeNextjsx react-jsxstrict路径别名typescript 编译选项browser bundlertype declaration