How do you get __dirname and __filename inside an ES module?
They do not exist in ES modules. Use import.meta.url with fileURLToPath and path.dirname, or on recent Node versions import.meta.dirname and import.meta.filename.
Explain it simply
__dirname and __filename are not real globals. In CommonJS, Node wraps every file in a function and passes them in as arguments. ES modules are not wrapped that way, so those names are simply undefined and using them throws a ReferenceError.
What ES modules do have is import.meta.url, the file's own address written as a URL like file:///home/app/src/server.js. You convert that URL into a normal path.
Example
import { fileURLToPath } from "node:url";
import path from "node:path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const uploads = path.join(__dirname, "uploads");
console.log(uploads);On recent Node versions (20.11 and 21.2 onwards) there is a shorter way: import.meta.dirname and import.meta.filename give you the same values directly.
Do not build paths with new URL(...).pathname on Windows; fileURLToPath handles drive letters and encoded characters correctly.
What to say in the interview
"ES modules have no __dirname because they are not wrapped in the CommonJS function wrapper. I derive it from import.meta.url using fileURLToPath and path.dirname, or use import.meta.dirname on newer Node."
Common mistakes
- Using
path.dirname(import.meta.url)and getting afile:URL instead of a path. - Using
process.cwd()as a replacement; it is the folder you started Node from, not the file's folder.