DevBolt
Processed in your browser. Your data never leaves your device.

TypeScript Module Resolution Guide

TypeScript's moduleResolution setting controls how import statements are resolved to files. Use the builder above to switch between strategies and see how it changes your tsconfig.json.

tsconfig.json Visual Builder

Build your TypeScript configuration visually with explanations for every option. Start from a preset or customize from scratch.

Presets

target

Set the JavaScript language version for emitted output.

module

Specify what module code is generated.

moduleResolution

Strategy for resolving import specifiers.

lib

Library files to include in the compilation.

Enables: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, alwaysStrict, useUnknownInCatchVariables


Additional (not included in strict)

include
src
exclude
node_modules
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true
  },
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules"
  ]
}

7

Options set

ON

Strict mode

302

Bytes

Press Ctrl+Enter to copy

Module resolution strategies explained

TypeScript offers 5 module resolution strategies: 'Node' (legacy, mimics Node.js require()), 'Node16'/'NodeNext' (modern Node.js with package.json exports support), 'Bundler' (for Webpack/Vite/esbuild/Turbopack), and 'Classic' (TypeScript 1.x legacy, avoid). Most new projects should use 'Bundler' for frontend or 'Node16'/'NodeNext' for backend.

When to use Bundler resolution

Use 'Bundler' when your code is processed by a bundler (Webpack, Vite, esbuild, Turbopack, Rollup). Bundler resolution allows extensionless imports (import './utils' resolves to utils.ts), respects package.json 'exports' field, and supports conditional exports. This is the right choice for React, Next.js, Vue, and most frontend projects.

When to use Node16 / NodeNext

Use 'Node16' or 'NodeNext' for pure Node.js projects that run without a bundler. These strategies enforce Node.js ESM rules: imports must include file extensions (import './utils.js'), package.json must have '"type": "module"' for ESM, and both require() and import can coexist based on file extension (.mjs/.cjs). Use 'NodeNext' to always track the latest Node.js behavior.

Module and moduleResolution pairing

Common pairings: ESNext + Bundler (frontend/bundled projects), Node16 + Node16 (Node.js ESM), CommonJS + Node (legacy Node.js). Mismatched pairs cause confusing errors. TypeScript 5.2+ recommends setting both module and moduleResolution explicitly rather than relying on defaults.

Frequently Asked Questions

What is the difference between Node and Node16 module resolution?

Node (legacy) mimics classic Node.js require() resolution — it checks node_modules, index.js, and JSON files. Node16 adds support for package.json 'exports' field, ESM/CJS dual packages, and requires file extensions in ESM imports. Use Node16 for any Node.js project using modern packages.

Why do I get 'Cannot find module' errors after changing moduleResolution?

Each strategy resolves imports differently. Switching from 'Node' to 'Node16' may require adding file extensions to imports. Switching to 'Bundler' may fix extensionless imports that 'Node16' rejected. Check that your module and moduleResolution are a compatible pair.

Should I use ESNext or ES2022 for the module setting?

Use ESNext for frontend/bundled projects — it always targets the latest ECMAScript module features. Use ES2022 or Node16 for Node.js when you want predictable, stable behavior that matches a specific Node.js version's module semantics.

Related Generate Tools