tsconfig.json Builder

Generate a TypeScript configuration for any project type or strictness level

Generate a tsconfig.json tuned for Node, React, or a publishable library — with the right target, module, moduleResolution, strict flags, paths, outDir, and declaration options for your project type. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What strict flags does the strict option enable?

Setting strict to true turns on a family of checks at once: strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitAny, noImplicitThis, useUnknownInCatchVariables, and alwaysStrict. It is the recommended baseline for new projects.

Generate a tsconfig.json that fits your project

tsconfig.json controls how the TypeScript compiler interprets and emits your code. The right settings differ sharply between a Node service, a React app compiled by a bundler, and a library you publish to npm. This builder asks what you are building and produces a sensible, modern configuration with the correct target, module, moduleResolution, strictness flags, and output options.

How it works

The output is a single compilerOptions object plus include/exclude arrays. The builder selects defaults by project type:

  • Node appmodule: "nodenext", moduleResolution: "nodenext", emit enabled to outDir.
  • React / bundlermodule: "esnext", moduleResolution: "bundler", jsx: "react-jsx", and noEmit: true because the bundler emits.
  • Library — emit enabled with declaration: true and declarationMap: true so consumers get type definitions and go-to-definition.

Strictness layers on top. A typical strict config looks like:

{
  "compilerOptions": {
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  }
}

Path aliases are written as a baseUrl plus a paths map. Remember the aliases must also be configured in your runtime or bundler — tsconfig only teaches the type-checker about them.

Key settings by project type

Node.js application or API

Use "module": "nodenext" and "moduleResolution": "nodenext" to match how Node’s native ESM loader resolves imports. This requires .js extensions on relative imports (even in .ts files), which surprises developers coming from bundler projects.

{
  "compilerOptions": {
    "target": "es2022",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "outDir": "./dist",
    "strict": true
  }
}

React or Vite / Next.js application

The bundler handles output; TypeScript only needs to type-check. Setting noEmit: true makes that explicit and prevents accidental dual-compilation:

{
  "compilerOptions": {
    "target": "es2020",
    "module": "esnext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "noEmit": true,
    "strict": true
  }
}

Published npm library

Consumers of your library need .d.ts type-definition files. Emit JavaScript and declarations together:

{
  "compilerOptions": {
    "target": "es2020",
    "module": "esnext",
    "moduleResolution": "bundler",
    "declaration": true,
    "declarationMap": true,
    "outDir": "./dist",
    "strict": true
  }
}

declarationMap adds source-map support so a user’s IDE “Go to definition” jumps to your original .ts source rather than the compiled .d.ts.

Tips and notes

  • Start strict, loosen laterstrict: true enables a family of checks at once. Retrofitting strictness onto a large untyped codebase is painful; start strict from day one.
  • skipLibCheck: true speeds builds significantly by trusting third-party .d.ts files. It hides real bugs in those files, but almost every real project uses it.
  • noUncheckedIndexedAccess is not part of strict but is highly recommended: accessing array[i] returns T | undefined rather than T, catching a real class of bugs.
  • Path aliases need both sides configuredtsconfig paths teach only the type-checker. Your bundler (Vite resolve.alias, webpack resolve.alias, Node --experimental-specifier-resolution) must be configured separately with matching rules.
  • target vs libtarget controls which JS syntax is emitted; lib controls which type declarations are available. They are independent. A target: "es5" project can still use lib: ["es2022"] if it polyfills at runtime.