Node.js ES modules require explicit file extensions in import paths. Unlike CommonJS (require), the module resolver does not try .js, .ts, or /index.js automatically.
The Fix
Add the file extension to your import:
// Wrong
import { handler } from "./routes/auth";
// Correct
import { handler } from "./routes/auth.js";
Yes, use .js even if your source file is .ts. TypeScript compiles .ts to .js, and Node resolves imports at runtime against the compiled output.
Root cause
When "type": "module" is set in package.json, Node uses the ESM resolver. The ESM spec requires explicit extensions, unlike CommonJS which probes multiple extensions.
Also check
package.jsonhas"type": "module"if you’re usingimport/exportsyntaxtsconfig.jsonhas"moduleResolution": "nodenext"or"bundler"for proper TypeScript ESM support- Directory imports need
/index.js:import { foo } from "./utils/index.js", not"./utils"
If you’re using a bundler
Bundlers (Vite, esbuild, webpack) resolve imports themselves and don’t need file extensions. This error only happens when Node.js resolves imports directly (server-side code, scripts, tests without a bundler).