/config/typescript/tsconfig-moduleresolution
tsconfig moduleResolution: bundler, nodenext, node16
verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated 2026-10-20
- tool
- TypeScript
- file
- tsconfig.json
- key
- compilerOptions.moduleResolution
- type
- "bundler" | "node16" | "nodenext"
compilerOptions.moduleResolution decides how the TypeScript compiler turns an import specifier such as "./util" or "react" into a file on disk. In TypeScript 7 the valid values are bundler, node16 and nodenext; node10 (alias node) and classic were removed.
Which value to use
bundler: the code is built by a bundler (Vite, webpack, esbuild, Bun, Next.js). Supportspackage.jsonexports, and does not require file extensions in relative imports.nodenext: Node.js runs the emitted JavaScript. Follows Node's rules: ES modules need explicit extensions,exportsandimportsare honoured. Must be paired with"module": "nodenext".node16: likenodenextbut frozen to Node 16 behaviour. Must be paired with"module": "node16".
Valid combinations with module (TypeScript 7.0.2)
Each cell was checked with tsc 7.0.2 on an empty project:
| moduleResolution | module esnext | module commonjs | module nodenext |
|---|---|---|---|
| bundler | ok | ok | error TS5095 |
| nodenext | error TS5110 | error TS5110 | ok |
| node16 | error TS5110 | error TS5110 | ok |
| node / node10 | error TS5108 (removed) | error TS5108 | error TS5108 |
| classic | error TS5108 (removed) | error TS5108 | error TS5108 |
npm init -y >/dev/null
npm install --silent --no-audit --no-fund typescript@7.0.2 >/dev/null 2>&1
echo 'export const x: number = 1;' > a.ts
for pair in esnext:bundler nodenext:nodenext esnext:nodenext; do
m=${pair%:*}; mr=${pair#*:}
echo "{ \"compilerOptions\": { \"module\": \"$m\", \"moduleResolution\": \"$mr\", \"noEmit\": true } }" > tsconfig.json
echo "module=$m moduleResolution=$mr:"; npx tsc && echo " ok"
done; trueOutput
module=esnext moduleResolution=bundler: ok module=nodenext moduleResolution=nodenext: ok module=esnext moduleResolution=nodenext: tsconfig.json(1,34): error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
Example: a Vite or webpack project
{
"compilerOptions": {
"target": "es2022",
"module": "esnext",
"moduleResolution": "bundler",
"noEmit": true
}
}Pitfalls
bundlerwith"module": "nodenext"fails with TS5095: bundler resolution only works withpreserve,commonjs, ores2015and later.- With
nodenext, an ES module import of./utilmust be written./util.js, even though the source file isutil.ts. - On TypeScript 6,
node10andclassicstill work behind"ignoreDeprecations": "6.0"; on TypeScript 7 they are gone (TS5108).
Sources
Related pages
errors · typescripterror TS5108: Option 'moduleResolution=node10' has been removedTypeScript 7 removed moduleResolution node and node10. Use bundler for code built by a bundler, or nodenext with module nodenext for code that Node.js runs.flags · bashset -euo pipefail: what each flag does in bashset -e exits on the first failing command, -u treats unset variables as errors and -o pipefail makes a pipeline fail if any command in it fails. Examples.compare · javascript== vs === in JavaScript: loose vs strict equality=== compares value and type without conversion; == converts types first, so 0 == '' and null == undefined are true. When to use each, with results from Node.js.