How to fix 'moduleResolution' should be 'node' or 'classic' in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025· 229 views

This TypeScript configuration error occurs when an invalid value is set for the moduleResolution compiler option in tsconfig.json. The fix involves correcting the moduleResolution value to one of the valid options: 'node', 'node16', 'nodenext', 'classic', or 'bundler'.

Quick fix

Fixes 'moduleResolution' should be 'node' or 'classic'

// tsconfig.json
{
  "compilerOptions": {
    // Look for this line:
    "moduleResolution": "node",  // Should be one of: node, node16, nodenext, classic, bundler
    // Other options...
  }
}
  1. Verify your current moduleResolution value
  2. Choose the correct moduleResolution value for your project
  3. Update your TypeScript version if needed
  4. Fix JSON syntax and configuration inheritance
typescript — error
// tsconfig.json
{
"compilerOptions": {
// Look for this line:
"moduleResolution": "node", // Should be one of: node, node16, nodenext, classic, bundler
// Other options...
}
}
'moduleResolution' should be 'node' or 'classic'

What this error means

The "'moduleResolution' should be 'node' or 'classic'" error appears when TypeScript encounters an invalid value for the `moduleResolution` compiler option in your tsconfig.json file. This option controls how TypeScript resolves module imports and must be set to one of the officially supported values. Module resolution is a critical part of TypeScript's compilation process. It determines how the compiler finds the files referenced in import statements. When you specify an unsupported value, TypeScript cannot proceed with compilation because it doesn't know how to resolve your module imports. Historically, TypeScript supported only 'node' and 'classic' resolution strategies. Modern versions have added 'node16', 'nodenext', and 'bundler' options to support newer JavaScript module systems and bundlers. The error message mentioning only 'node' or 'classic' can be misleading if you're using a newer TypeScript version that supports additional options.

Typical symptoms

  • TypeScript compilation fails with the error: "'moduleResolution' should be 'node' or 'classic'"
  • IDE shows configuration errors in tsconfig.json file
  • Build process fails immediately when running tsc or related commands
  • Auto-completion and type checking may not work in the IDE
  • Error occurs even before any TypeScript code is compiled

Common causes

  1. Typo in the moduleResolution value (e.g., 'nodes', 'Node', 'nod' instead of 'node')
  2. Using an outdated TypeScript version that doesn't support newer options like 'node16' or 'bundler'
  3. Copy-pasting configuration from an incompatible source or framework
  4. Incorrect JSON syntax in tsconfig.json (missing quotes, wrong data type)
  5. Using a value that was valid in older TypeScript versions but removed in newer releases
  6. Configuration file inheritance issues where a base tsconfig.json has invalid settings

How to fix "'moduleResolution' should be 'node' or 'classic'"

1Verify your current moduleResolution value

First, check your tsconfig.json file to see what value is set for moduleResolution:

json
// tsconfig.json
{
  "compilerOptions": {
    // Look for this line:
    "moduleResolution": "node",  // Should be one of: node, node16, nodenext, classic, bundler
    // Other options...
  }
}

Common incorrect values to watch for:
- "moduleResolution": "Node" (capital N - should be lowercase)
- "moduleResolution": "nodes" (typo - missing 'e')
- "moduleResolution": "nod" (incomplete)
- "moduleResolution": "esnext" (this is for 'module', not 'moduleResolution')
- "moduleResolution": "commonjs" (this is for 'module', not 'moduleResolution')

If you don't see moduleResolution in your tsconfig.json, TypeScript uses a default value based on your 'module' setting.

2Choose the correct moduleResolution value for your project

Select the appropriate moduleResolution based on your project type:

json
{
  "compilerOptions": {
    // For Node.js projects (CommonJS):
    "moduleResolution": "node",
    "module": "commonjs",

    // For modern Node.js (ES modules with "type": "module" in package.json):
    "moduleResolution": "node16",  // or "nodenext"
    "module": "node16",            // or "nodenext"

    // For bundlers like webpack, Vite, esbuild:
    "moduleResolution": "bundler",
    "module": "esnext",

    // Legacy TypeScript resolution (rarely used):
    "moduleResolution": "classic",
    "module": "amd"  // or "system", "umd"
  }
}

Quick reference:
- Node.js CommonJS projects: Use "moduleResolution": "node"
- Node.js ES modules: Use "moduleResolution": "node16" or "nodenext"
- Frontend with bundler: Use "moduleResolution": "bundler"
- Legacy/rare cases: Use "moduleResolution": "classic"

3Update your TypeScript version if needed

Some moduleResolution values require newer TypeScript versions:

bash
# Check your current TypeScript version
npx tsc --version

# Update TypeScript globally
npm install -g typescript@latest

# Or update in your project
npm install --save-dev typescript@latest

# Verify the update
npm list typescript

Version requirements:
- "node16" and "nodenext": TypeScript 4.7+
- "bundler": TypeScript 5.0+
- "node" and "classic": All TypeScript versions

If you need to support older TypeScript versions but want modern module resolution, consider:
1. Upgrading TypeScript (recommended)
2. Using "moduleResolution": "node" with appropriate module settings
3. Configuring your bundler to handle module resolution

4Fix JSON syntax and configuration inheritance

Ensure your tsconfig.json has valid JSON syntax:

json
// WRONG - missing quotes
{
  "compilerOptions": {
    moduleResolution: node  // Should be "moduleResolution": "node"
  }
}

// WRONG - extra comma
{
  "compilerOptions": {
    "moduleResolution": "node",  // Trailing comma in JSON
  }
}

// CORRECT
{
  "compilerOptions": {
    "moduleResolution": "node"
  }
}

Check for configuration inheritance:
If you extend another tsconfig.json file:

json
// tsconfig.base.json
{
  "compilerOptions": {
    "moduleResolution": "invalid-value"  // This causes the error
  }
}

// tsconfig.json
{
  "extends": "./tsconfig.base.json",  // Inherits the invalid value
  "compilerOptions": {
    // Override the invalid value
    "moduleResolution": "node"
  }
}

Use a JSON validator to check syntax:

bash
# Using node
node -e "console.log(JSON.parse(require('fs').readFileSync('tsconfig.json', 'utf8')))"

# Using jq (if installed)
jq . tsconfig.json
5Test the fix and verify compilation

After fixing the moduleResolution value, test your configuration:

bash
# Run TypeScript compiler to check for errors
npx tsc --noEmit

# If using a build script
npm run build

# Check specific files
npx tsc src/index.ts --noEmit

Verify module resolution is working:
Create a test file to ensure imports resolve correctly:

typescript
// test-import.ts
import * as path from "path";  // Node.js built-in
import React from "react";     // External package
import { myUtil } from "./utils";  // Local file

console.log("Module resolution is working!");

Compile it:

bash
npx tsc test-import.ts --noEmit

If you still get errors, check:
1. The exact spelling of "moduleResolution" (case-sensitive)
2. That the value is a string, not a number or boolean
3. That there are no hidden characters or encoding issues

6Configure for specific frameworks and tools

Different frameworks have preferred moduleResolution settings:

Next.js:

json
{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "module": "esnext",
    "target": "es5"
  }
}

React with Create React App:

json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "esnext",
    "target": "es5"
  }
}

Angular:

json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "es2020",
    "target": "es2020"
  }
}

NestJS:

json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "commonjs",
    "target": "es2017"
  }
}

If using a framework template:
Check the framework's documentation or starter template for the recommended tsconfig.json configuration. Many frameworks provide a base tsconfig.json that you should extend rather than modifying directly.

Advanced notes

### Historical Context and Error Message

The error message "'moduleResolution' should be 'node' or 'classic'" originates from TypeScript's early versions when only these two options existed. Despite newer options being added, the error message hasn't been updated in all cases. This can be confusing when you're trying to use 'node16', 'nodenext', or 'bundler'.

### moduleResolution vs module

It's important to distinguish between moduleResolution and module:

- `module`: Determines the module system for the output JavaScript (commonjs, es2015, esnext, etc.)
- `moduleResolution`: Determines how TypeScript finds the source modules during compilation

Common mismatches:

json
// WRONG - moduleResolution doesn't match module
{
  "module": "esnext",
  "moduleResolution": "node"  // Should be "bundler" for esnext with bundlers
}

// CORRECT - aligned settings
{
  "module": "esnext",
  "moduleResolution": "bundler"  // For bundlers like webpack, Vite
}

### TypeScript Version Compatibility Matrix

| moduleResolution | TypeScript | Use Case |
|-----------------|------------|----------|
| classic | 1.0+ | Legacy AMD/System.js projects |
| node | 1.0+ | Node.js CommonJS (default for commonjs module) |
| node16 | 4.7+ | Node.js ES modules (package.json "type": "module") |
| nodenext | 4.7+ | Same as node16, future-proof naming |
| bundler | 5.0+ | Modern bundlers (webpack, Vite, esbuild, etc.) |

### Debugging Module Resolution

To see how TypeScript resolves modules:

bash
# Trace module resolution for a specific file
npx tsc --traceResolution src/index.ts

# See all resolution attempts
npx tsc --traceResolution | grep "======== Resolving module"

# Check which tsconfig.json is being used
npx tsc --showConfig

### Common Pitfalls

1. Framework-specific configurations: Some frameworks (like Angular) have their own compilation pipeline and may ignore certain tsconfig.json settings.

2. Monorepos: In monorepos, each package might need its own tsconfig.json with appropriate moduleResolution settings based on its role (library vs application).

3. Mixed module systems: If you have both CommonJS and ES modules in your project, you may need to use "moduleResolution": "node16" with proper package.json configuration.

4. Bundler plugins: Some bundlers have plugins that affect TypeScript compilation (like @vitejs/plugin-react for Vite). Ensure these are configured correctly.

### Migration Strategies

When migrating from older TypeScript versions or module systems:

1. From classic to node: Update imports to use Node.js resolution rules (no .ts extensions, index file resolution).
2. From node to node16: Add .js extensions to relative imports in TypeScript source files.
3. To bundler: Ensure your bundler is configured to match TypeScript's resolution strategy.

### References

- [TypeScript Module Resolution Documentation](https://www.typescriptlang.org/docs/handbook/module-resolution.html)
- [TSConfig moduleResolution Reference](https://www.typescriptlang.org/tsconfig#moduleResolution)
- [Node.js Module Resolution](https://nodejs.org/api/esm.html#resolution-algorithm)
- [Bundler Module Resolution](https://www.typescriptlang.org/docs/handbook/modules/reference.html#bundler)

Frequently asked questions

What does "'moduleResolution' should be 'node' or 'classic'" mean?
json file. This option controls how TypeScript resolves module imports and must be set to one of the officially supported values. Module resolution is a critical part of TypeScript's compilation process.
How do I fix "'moduleResolution' should be 'node' or 'classic'"?
This TypeScript configuration error occurs when an invalid value is set for the moduleResolution compiler option in tsconfig.json. The fix involves correcting the moduleResolution value to one of the valid options: 'node', 'node16', 'nodenext', 'classic', or 'bundler'.
What causes "'moduleResolution' should be 'node' or 'classic'"?
Typo in the moduleResolution value (e.g., 'nodes', 'Node', 'nod' instead of 'node') Using an outdated TypeScript version that doesn't support newer options like 'node16' or 'bundler' Copy-pasting configuration from an incompatible source or framework
Is the "'moduleResolution' should be 'node' or 'classic'" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading