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
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
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
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
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
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
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
| Preset |
|---|
| Next.js (App Router) |
| Vite + React |
| Node.js (ESM) |
| Node.js (CommonJS) |
| TypeScript Library |
| Deno |
Every option you can configure is grouped into the categories above: Type Checking, Modules & Resolution, Output, Interop & Compatibility, Include & Exclude.
When to use TSConfigBuilder
| Scenario |
|---|
| Starting a new Next.js, Vite, or Node project |
| Migrating from CommonJS to ESM |
| Understanding what strict mode actually checks |
| Setting up a @/* import alias |
| Auditing an existing tsconfig.json |
| Sharing a team standard config |
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.
| Option | Controls | Common value |
|---|---|---|
| module | What module syntax is emitted / expected | ESNext (bundler), NodeNext (Node ESM), CommonJS (legacy Node) |
| moduleResolution | How import paths are resolved to files | Bundler (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.
{
"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 --init | TSConfigBuilder | |
|---|---|---|
| Setup required | Node.js + TypeScript installed | None, runs in browser |
| Output | Generic config with every option commented out | Framework-specific config with only relevant options set |
| Explanations | One-line comments | Plain-English explanation + 'why you'd set this' for every option |
| Framework presets | No | Next.js, Vite, Node ESM/CJS, library, Deno |
| Compare configs | No | Built-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.