Dev Encyclopedia
ArticlesTools

Get notified when new content drops

No spam. Just new articles, tools, and updates straight to your inbox.

Dev Encyclopedia

A reference for builders

Content

  • Articles
  • Tools
  • Contact

Connect

  • support@devencyclopedia.com
  • RSS Feed

© 2026 Dev Encyclopedia

Privacy PolicyTermsDisclaimer
  1. Home
  2. /
  3. Tools
  4. /
  5. TSConfigBuilder
Free · Private · No setup

The tsconfig.json you actually understand.

Pick your framework, toggle compiler options, and read a plain-English explanation for every one. Get a correct tsconfig.json in under 2 minutes, not one copied from Stack Overflow three years ago.

How TSConfigBuilder works

  1. 1

    Pick a framework preset

    Choose Next.js, Vite + React, Node.js (ESM or CommonJS), a TypeScript library, or Deno. Each preset pre-fills target, module, moduleResolution, lib, and other framework-specific options with sensible defaults.

  2. 2

    The JSON output updates instantly

    The tsconfig.json panel reflects your current selections in real time, formatted exactly as you'd paste it into your project.

  3. 3

    Toggle individual options

    Every option is grouped by category: Type Checking, Modules & Resolution, Output, Interop & Compatibility, and Include & Exclude. Flip a switch, pick from a dropdown, or edit a glob list.

  4. 4

    Read the plain-English explanation

    Each option shows what it does and a 'Why' note explaining when and why you'd enable it, no tab-switching to the TypeScript docs.

  5. 5

    Compare presets with the diff view

    Pick a second framework preset to compare against. The diff table shows exactly which compilerOptions differ between the two, useful for understanding what changes if you switch stacks.

  6. 6

    Copy, download, or share

    Copy the JSON to your clipboard, download it as tsconfig.json, or generate a share link that encodes your exact configuration in the URL for teammates.

What each option category controls

tsconfig.json options fall into a handful of groups. Understanding what each group is responsible for makes the individual options much easier to reason about.

Type Checking

Controls how strict TypeScript is about catching potential bugs: implicit any types, null/undefined handling, unused variables, and unsafe index access. Start with strict: true and add the others as needed.

Modules & Resolution

Controls how your import/export statements are written, compiled, and resolved to files on disk, including module, moduleResolution, baseUrl, and path aliases like @/*.

Output

Controls what TypeScript produces: which JS version (target), which built-in APIs are available (lib), JSX handling, and whether it emits files at all (noEmit) or writes to outDir.

Interop & Compatibility

Smooths over differences between CommonJS and ES modules, third-party type definitions, and case-sensitive file systems so your code behaves the same across environments.

Include & Exclude

Defines which files are part of the TypeScript project at all. Scoping this correctly keeps build output, config files, and node_modules out of the type-checker.

Framework presets

PresetWhat it sets up
Next.js (App Router)TypeScript + JSX, bundler resolution, @/* path alias to src/.
Vite + ReactTypeScript + JSX with the modern automatic runtime, bundler resolution.
Node.js (ESM)Modern Node module resolution, compiles to dist/ with declarations and source maps.
Node.js (CommonJS)Classic require()/module.exports Node project, compiles to dist/.
TypeScript LibraryPublishable npm package: declarations, source maps, isolated modules.
DenoESM-native runtime, no CommonJS interop needed.

Every option you can configure is grouped into the categories above: Type Checking, Modules & Resolution, Output, Interop & Compatibility, Include & Exclude.

When to use TSConfigBuilder

ScenarioWhat to do
Starting a new Next.js, Vite, or Node projectClick the matching preset and copy the output
Migrating from CommonJS to ESMCompare a CJS preset with an ESM preset in the diff view
Understanding what strict mode actually checksToggle strict and read each Type Checking explanation
Setting up a @/* import aliasFill in paths: alias and paths: target in Modules & Resolution
Auditing an existing tsconfig.jsonRecreate your settings here and read the 'Why' for anything unfamiliar
Sharing a team standard configConfigure it once, then use Share to send a link that restores it

Frequently Asked Questions

What is tsconfig.json?

tsconfig.json is the configuration file that tells the TypeScript compiler how to type-check and (optionally) compile your project. It lives at the root of your project and controls things like which JavaScript version to target, how modules are resolved, how strict type checking should be, and which files are part of the project.

Tools like Next.js, Vite, and the TypeScript language server in your editor all read this file to know how to interpret your code.

What does strict do in tsconfig.json?

strict is a single flag that turns on a whole group of stricter type-checking options at once, including noImplicitAny (no silent any types), strictNullChecks (null and undefined must be handled explicitly), strictFunctionTypes, and several others.

It's the single most impactful option in tsconfig.json. Every new TypeScript project should start with strict: true. Use the toggles in the tool above to see exactly which checks it enables and why each one matters.

What is the difference between module and moduleResolution in tsconfig?

module controls the module syntax TypeScript outputs when it compiles your code, for example whether import statements become require() calls (CommonJS) or stay as import/export (ESNext, NodeNext).

moduleResolution controls how TypeScript finds the actual file behind an import statement, including whether it checks for index.ts files, file extensions, and package.json exports fields.

OptionControlsCommon value
moduleWhat module syntax is emitted / expectedESNext (bundler), NodeNext (Node ESM), CommonJS (legacy Node)
moduleResolutionHow import paths are resolved to filesBundler (Vite/Next.js/webpack), NodeNext (Node ESM), Node (legacy)

In short: module is about output format, moduleResolution is about file lookup. They're usually set together based on your runtime or bundler.

What does skipLibCheck do in tsconfig.json?

skipLibCheck: true tells TypeScript to skip type-checking inside .d.ts declaration files, including the ones bundled with packages in node_modules.

Without it, a single incorrect or conflicting type definition in a third-party package can break your entire build with errors you can't fix. It also speeds up compilation noticeably on large projects. Almost every modern tsconfig.json, including the official Next.js and Vite templates, sets this to true.

What tsconfig.json should I use for Next.js?

Click the "Next.js (App Router)" preset in the tool above to generate a complete config. The key settings are moduleResolution: "Bundler" (so TypeScript resolves imports the same way Next.js does), jsx: "preserve" (Next.js handles the JSX transform), and a @/ path alias pointing at ./src/ for clean imports.

json
{
  "compilerOptions": {
    "target": "ES2017",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "jsx": "preserve",
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}
Does TSConfigBuilder send my config anywhere?

No. Everything runs in your browser: presets, option toggles, JSON generation, and the diff view. Nothing is uploaded to a server. The Share button encodes your current configuration into the URL itself, so sharing a link doesn't send anything to us either.

How is this different from running tsc --init?
tsc --initTSConfigBuilder
Setup requiredNode.js + TypeScript installedNone, runs in browser
OutputGeneric config with every option commented outFramework-specific config with only relevant options set
ExplanationsOne-line commentsPlain-English explanation + 'why you'd set this' for every option
Framework presetsNoNext.js, Vite, Node ESM/CJS, library, Deno
Compare configsNoBuilt-in preset diff view

tsc --init is a good starting point if you already understand the options and just want a file to edit. TSConfigBuilder is for getting a correct, framework-tuned config quickly while learning what each option actually does.

Do I need baseUrl to use path aliases like @/*?

In TypeScript 5 and later, paths can be used without baseUrl, they're resolved relative to the tsconfig.json file itself. Older TypeScript versions (4.x and earlier) require baseUrl to be set alongside paths, typically to ".".

If your editor or build tool reports 'cannot find module @/...' even though paths is set correctly, check your TypeScript version first, then make sure your bundler (Vite, webpack) has a matching alias configured, since paths only affects type-checking, not the actual module resolution at runtime.

Related reading

Guide

TypeScript 7 (Project Corsa): What Next.js Devs Need to Know

TypeScript's native-speed compiler is coming. See how it affects the tsconfig.json options you configure above.

Tool

SemverExplainer: npm Semver Range Explainer

Once your tsconfig is set up, make sure your TypeScript and @types/* version ranges in package.json are correct too.

Framework presets

TypeScript + JSX, bundler resolution, @/* path alias to src/.

{
  "compilerOptions": {
    "strict": true,
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "allowJs": true,
    "target": "ES2017",
    "jsx": "preserve",
    "lib": [
      "DOM",
      "DOM.Iterable",
      "ESNext"
    ],
    "noEmit": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "forceConsistentCasingInFileNames": true,
    "paths": {
      "@/*": [
        "./src/*"
      ]
    }
  },
  "include": [
    "next-env.d.ts",
    "src/**/*.ts",
    "src/**/*.tsx",
    ".next/types/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

Type Checking

strict

Enables all strict type-checking options at once, including noImplicitAny, strictNullChecks, and strictFunctionTypes.

Why: Turn this on for every new project. It's the single most impactful option here and catches the largest class of TypeScript bugs before they ship.

noImplicitAny

Raises an error whenever TypeScript can't infer a type and would otherwise silently fall back to any.

Why: Already included by strict. Enable it on its own when migrating a JavaScript codebase gradually and you want this check before turning on full strict mode.

strictNullChecks

Makes null and undefined distinct types that must be explicitly handled, instead of being assignable to anything.

Why: Already included by strict. This single option eliminates most 'cannot read property of undefined' runtime errors.

noUncheckedIndexedAccess

Adds | undefined to the result of any index signature access, like arr[i] or record[key].

Why: Turn this on if your code reads from arrays or objects by dynamic key and you've been bitten by missing-key or out-of-bounds bugs that strict mode alone doesn't catch.

noUnusedLocals

Reports an error for any local variable that's declared but never read.

Why: Useful for keeping a codebase tidy, but can be noisy during active development. Many teams enforce this with ESLint instead.

noUnusedParameters

Reports an error for function parameters that are never used (prefix a parameter with _ to exempt it).

Why: Same trade-off as noUnusedLocals. Pairs well with ESLint's no-unused-vars if you want this enforced project-wide instead.

Modules & Resolution

module

Controls the module syntax TypeScript emits (require vs import) and what module syntax it expects in your code.

Why: Match this to your runtime: NodeNext for modern Node ESM/CJS interop, ESNext when a bundler like Vite or Next.js handles module output, CommonJS for older Node projects.

moduleResolution

Controls the algorithm TypeScript uses to find the files behind an import statement.

Why: Use Bundler with Vite, Next.js, or webpack, it matches how bundlers actually resolve imports including extensionless paths. Use NodeNext for Node.js ESM, and Node for legacy CommonJS.

baseUrl

Sets a base directory that non-relative module names are resolved from.

Why: Older TypeScript versions require this when using paths. With moduleResolution: bundler and TS 5+, most setups can leave this empty and rely on paths alone.

paths: alias

The import specifier pattern you want to use, for example @/* to write @/components/Button instead of a relative path.

Why: Set this up once per project, then mirror the same alias in your bundler config (e.g. Vite's resolve.alias) so both TypeScript and your build tool agree.

paths: target

The file system location the alias above maps to, for example ./src/*.

Why: Together, pathAlias and pathTarget generate the paths map in compilerOptions, the most common source of 'cannot find module @/...' errors when misconfigured.

resolveJsonModule

Allows importing .json files as modules, with types inferred automatically from their contents.

Why: Turn this on if you import config or data files as JSON anywhere in your code, very common in Node and Next.js projects.

allowJs

Allows .js and .jsx files to be imported and type-checked alongside .ts files.

Why: Enable during a gradual JavaScript-to-TypeScript migration, or if your project intentionally mixes JS and TS files (common in Next.js projects with legacy scripts).

Output

target

Sets the JavaScript language version TypeScript compiles down to, and which built-in syntax and APIs are assumed to exist.

Why: Set this to the oldest runtime you need to support. For modern Node.js or evergreen browsers, ES2022 or ESNext is safe and avoids unnecessary downleveling.

jsx

Controls how JSX syntax is compiled: left as-is for a bundler, transformed using the modern automatic runtime, or transformed to React.createElement calls.

Why: Use preserve when a bundler like Next.js or Vite handles the JSX transform itself. Use react-jsx for the modern automatic runtime in plain TypeScript + React projects.

lib

Specifies which built-in type definitions are available globally, for example DOM for window/document or ES2022 for modern array and object methods.

Why: Frontend projects need DOM and DOM.Iterable. Node.js and other non-browser projects should omit DOM libs entirely to avoid accidentally relying on browser globals.

outDir

The folder where compiled .js output files are written.

Why: Required for any project that runs tsc to produce build output, libraries and Node services especially. Not needed when a bundler or framework compiles your code instead.

rootDir

The root folder of your input source files, used to mirror your source structure inside outDir.

Why: Set this alongside outDir so compiled output preserves the same folder layout as your source, typically ./src.

declaration

Generates .d.ts type declaration files alongside your compiled output.

Why: Required if you're publishing a package that other TypeScript projects will import, so consumers get full type information.

sourceMap

Generates .js.map files that map compiled output back to your original TypeScript source.

Why: Turn this on for any project where you'll debug compiled output, libraries and Node services especially.

noEmit

Tells TypeScript to type-check your code without writing any output files.

Why: Set this to true whenever a separate tool (Next.js, Vite, esbuild, Babel) compiles your code. TypeScript's only job then is type-checking.

Interop & Compatibility

esModuleInterop

Allows default imports from CommonJS modules that don't have a default export, for example import express from 'express'.

Why: Almost always should be on. Without it you'd need import * as express from 'express' for many popular packages.

allowSyntheticDefaultImports

Allows default-import syntax for modules without a default export, for type-checking purposes only (it doesn't change emitted JS).

Why: Usually implied by esModuleInterop. Set it explicitly if a bundler already handles the interop at runtime but TypeScript still complains.

skipLibCheck

Skips type-checking of all .d.ts declaration files, including those in node_modules.

Why: Turn this on in almost every project. It avoids errors from conflicting or slightly-incorrect third-party types and significantly speeds up compilation.

isolatedModules

Requires every file to be safely compilable on its own, without relying on information from other files (for example, disallows re-exporting types without export type).

Why: Required by single-file transpilers like esbuild, SWC, and Babel, which is what Next.js, Vite, and most modern bundlers use under the hood.

forceConsistentCasingInFileNames

Ensures that references to the same file use consistent capitalization, e.g. ./Button vs ./button.

Why: Prevents bugs that only show up on case-sensitive file systems (Linux CI servers) after working fine on case-insensitive ones (macOS, Windows).

Include & Exclude

include

An array of glob patterns specifying which files TypeScript should include in the project.

Why: Scope this to your source folder (e.g. src/**/*) so TypeScript doesn't try to type-check generated files, build output, or config files.

exclude

An array of glob patterns specifying files to exclude, even if they'd otherwise match include.

Why: Always exclude node_modules and your build output directory. TypeScript excludes node_modules by default, but it's good practice to be explicit.

Compare Next.js (App Router) with

OptionNext.js (App Router)Vite + React
allowJstrue—
jsxpreservereact-jsx
lib["DOM","DOM.Iterable","ESNext"]["ES2020","DOM","DOM.Iterable"]
noUnusedLocals—true
noUnusedParameters—true
targetES2017ES2020