strict: true, moduleResolution: "bundler" (or "nodenext"), target: "es2022", and skipLibCheck: true.tsc --showConfigpaths aliases without configuring the same aliases in your bundler — TypeScript does NOT rewrite import paths.strict: true is non-negotiable for new projectsmoduleResolution must match your module setting — "bundler" for Vite/webpack, "nodenext" for pure Node.jsskipLibCheck: false in large projects — dramatically slows compilationtarget and lib are separate concerns — target controls emit, lib controls typespaths aliases require bundler config too — TypeScript does NOT rewrite import paths| Option | Recommended | Purpose |
|---|---|---|
strict | true | All strict type checks |
target | "es2022" | Emit syntax level |
module | "esnext" / "nodenext" | Module system |
moduleResolution | "bundler" / "nodenext" | How TS finds modules |
skipLibCheck | true | Skip .d.ts checking |
isolatedModules | true | Required by esbuild/swc/Vite |
verbatimModuleSyntax | true | Explicit type-only imports |
noUncheckedIndexedAccess | true | Index returns T | undefined |
resolveJsonModule | true | Import .json files |
declaration | true (libs) | Generate .d.ts files |
incremental | true | Faster rebuilds |
noEmit | true (bundler) | Bundler handles emit |
START
├── Pure Node.js (no bundler)?
│ ├── YES → module: "nodenext", moduleResolution: "nodenext"
│ └── NO ↓
├── Using Vite, webpack, esbuild?
│ ├── YES → module: "esnext", moduleResolution: "bundler", noEmit: true
│ └── NO ↓
├── Building npm library?
│ ├── YES → declaration: true, declarationMap: true, outDir: "./dist"
│ └── NO ↓
├── React project?
│ ├── YES → jsx: "react-jsx"
│ └── NO ↓
├── Monorepo?
│ ├── YES → composite: true, references: [...]
│ └── NO ↓
└── DEFAULT → strict: true, target: "es2022", skipLibCheck: true
Generate a starter config. [src5]
npx tsc --init
Verify: ls tsconfig.json → file exists
Essential options for every project. [src2]
{
"compilerOptions": {
"strict": true,
"target": "es2022",
"skipLibCheck": true,
"esModuleInterop": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"noUncheckedIndexedAccess": true,
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true,
"moduleDetection": "force"
}
}
Choose based on bundler vs Node.js. [src4]
// For bundlers (Vite, webpack):
{ "module": "esnext", "moduleResolution": "bundler", "noEmit": true }
// For pure Node.js:
{ "module": "nodenext", "moduleResolution": "nodenext", "outDir": "./dist" }
{
"compilerOptions": {
"strict": true, "target": "es2022",
"lib": ["es2022", "dom", "dom.iterable"],
"module": "esnext", "moduleResolution": "bundler",
"isolatedModules": true, "noEmit": true,
"jsx": "react-jsx",
"skipLibCheck": true, "noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true,
"baseUrl": ".", "paths": { "@/*": ["./src/*"] }
},
"include": ["src", "vite-env.d.ts"]
}
{
"compilerOptions": {
"strict": true, "target": "es2022", "lib": ["es2022"],
"module": "nodenext", "moduleResolution": "nodenext",
"outDir": "./dist", "rootDir": "./src",
"sourceMap": true, "declaration": true, "incremental": true,
"skipLibCheck": true, "noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
{
"compilerOptions": {
"strict": true, "target": "es2022", "lib": ["es2022"],
"module": "esnext", "moduleResolution": "bundler",
"outDir": "./dist", "rootDir": "./src",
"declaration": true, "declarationMap": true, "sourceMap": true,
"skipLibCheck": true, "noUncheckedIndexedAccess": true,
"isolatedModules": true, "verbatimModuleSyntax": true
},
"include": ["src/**/*"],
"exclude": ["**/*.test.ts"]
}
// ❌ BAD — silent any, null bugs everywhere
{ "compilerOptions": { "strict": false, "target": "es5" } }
// ✅ GOOD — catches bugs at compile time
{ "compilerOptions": { "strict": true, "target": "es2022" } }
// ❌ BAD — "node" is legacy, misses package.json exports
{ "module": "esnext", "moduleResolution": "node" }
// ✅ GOOD — supports exports, no extension requirement
{ "module": "esnext", "moduleResolution": "bundler" }
module: "nodenext". [src3]vite-tsconfig-paths or tsconfig-paths. [src1]rm tsconfig.tsbuildinfo && npx tsc. [src6]"lib": ["es2022"] for Node.js. [src1]strict: true alone. [src2]# Show fully resolved tsconfig
npx tsc --showConfig
# Type-check without emitting
npx tsc --noEmit
# List files that would be compiled
npx tsc --listFiles
# Check TypeScript version
npx tsc --version
# Build with verbose diagnostics
npx tsc --extendedDiagnostics
| Version | Status | Key Additions | Notes |
|---|---|---|---|
| TS 5.7 | Current | — | Fully supports all listed options |
| TS 5.5 | Stable | isolatedDeclarations, extends arrays | — |
| TS 5.4 | Stable | verbatimModuleSyntax finalized | Replaces importsNotUsedAsValues |
| TS 5.0 | LTS | moduleResolution: "bundler" | First with bundler resolution |
| TS 4.x | EOL | — | Upgrade to 5.x |
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Any TypeScript project | Using Deno | deno.json compilerOptions |
| Need precise type checking | Quick prototype | Plain JS |
| Building npm libraries | Using Bun exclusively | bunfig.toml |
moduleResolution: "bundler" requires module: "esnext" or "preserve"verbatimModuleSyntax replaces older importsNotUsedAsValuescomposite: true requires declaration: true and disallows noEmit: true