Have you ever encountered the frustrating SyntaxError: The requested module ‘…’ does not provide an export named ‘…’ in your Node.js and TypeScript project?
What makes this issue extremely painful is its ghost-like behavior: your code works fine for hours, you make a minor change in a completely unrelated file, and suddenly the app crashes with this export error—even though the export clearly exists in your source code. Even weirder, if you delete your compiled .js files in the src/ directory, everything starts working again—only to break after a few edits!
Key Realization: This error does not always mean that the named export is actually missing. In mixed TypeScript, ESM, CommonJS, IDE loader, or stale build-output setups, Node.js may be loading or interpreting a completely different file/module version than you expect.
If this sounds familiar, don’t worry. This guide covers why this happens and how to permanently fix it.
🛠️ Why Does This Error Happen?
This issue primarily occurs due to a combination of environment conflicts:
1. The package.json vs tsconfig.json Mismatch
In modern Node.js applications, setting “type”: “module” in package.json tells Node.js to treat files as ES Modules (ESM). However, Node.js relies on your “type” field (and file extensions) to determine execution mode, whereas tsconfig.json controls how TypeScript generates output. If your tsconfig.json relies on “module“: “commonjs”, TypeScript generates CommonJS output (require()), leading to export resolution failures.
2. Double-Loader Conflict in IDEs (WebStorm)
If your IDE (like WebStorm) is configured to use a Bundled loader (like tsx) while your Node parameters simultaneously contain –require ts-node/register, two different mechanisms may try to handle TypeScript execution at the same time. This can lead to confusing or inconsistent module-loading behavior.
3. Direct Execution via node src/server.ts
Running a script like “start”: “node src/server.ts” directly without standardizing your TypeScript runtime runner (like tsx or ts-node) can result in unpredictable execution depending on your Node.js version and IDE settings.
4. Stale .js Files Polluting src/
When background compilation is enabled in your IDE or tsc runs without a designated output directory, .js files accumulate inside your src/ folder alongside .ts files. Depending on your runtime and import configuration, stale .js files may be loaded instead of the TypeScript source you intended to execute.
🚀 How to Fix the Error (Step-by-Step)
Step 1: Align Your Module Configuration (CJS vs ESM)
Ensure your package.json and tsconfig.json configurations are consistent:
❌ Conflicting Configuration
package.json
json
{
"type": "module"
}
tsconfig.json
json
{
"compilerOptions": {
"module": "commonjs"
}
}
✅ Consistent ESM Configuration
package.json
json
{
"type": "module"
}
tsconfig.json
json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}
Tip: Setting “outDir”: “./dist” ensures all generated JavaScript goes into a separate build directory, keeping your src folder clean.
Step 2: Fix WebStorm & Execution Runtime Conflicts
Avoid combining multiple runtime loaders. Choose one clear execution strategy:
Remove conflicting parameters: Open WebStorm Run/Debug Configurations, clear –require ts-node/register from Node parameters, and let WebStorm use tsx.
Standardize via package.json: Use tsx directly for running development scripts instead of relying on plain node.
bash
npm install -D tsx
Update your package.json scripts:
json
{
"scripts": {
"start": "tsx src/server.ts",
"dev": "tsx watch src/server.ts"
}
}
Step 3: Clean Stale .js Files from src/
Delete compiled JavaScript files interfering with your source code:
Linux / macOS:
bash
find src -name "*.js" -type f -delete
Windows (PowerShell):
powershell
Get-ChildItem -Path ./src -Filter *.js -Recurse | Remove-Item
Step 4: Add .js Extensions When Using Native Node.js ESM with NodeNext
Under native ES Modules with NodeNext resolution, relative imports require explicit .js extensions (even in TypeScript source code):
typescript
// ❌ Incorrect (CJS Style)
import { LoggerClass } from "../utils/LoggerClass";
// ✅ Correct (ESM Style with NodeNext)
import { LoggerClass } from "../utils/LoggerClass.js";
📌 Quick Resolution Summaryv
| Cause | Action |
|---|---|
| Config Mismatch | Align “type”: “module” with “module”: “NodeNext” |
| IDE Conflicts | Do not combine tsx loader with –require ts-node/register |
| Stale Output | Route builds to ./dist using outDir in tsconfig.json |
| Import Syntax | Append .js extensions to relative file imports when using native ESM |