Back to results for “Path & OS Modules”
Node.js › Global Objects & the process Object

What is the difference between __dirname/__filename in CommonJS and their equivalents in ES Modules?

Intermediate

Answer

In CommonJS, __dirname and __filename are automatically available in every module, providing the absolute path to the current file's directory and the file itself. ES Modules don't have these globals at all (since ESM was designed to be more portable, including for non-file-based module sources); the equivalent in ESM is derived from import.meta.url, typically converted to a filesystem path using the node:url module's fileURLToPath() function.
// CommonJS
console.log(__dirname);  // /path/to/current/directory
console.log(__filename); // /path/to/current/directory/file.js

// ES Modules equivalent
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Real-world example A team migrating a CommonJS codebase to ES Modules encounters build failures everywhere __dirname was used to resolve relative file paths, requiring them to add the fileURLToPath(import.meta.url) pattern at the top of each affected file as part of the migration.

Common follow-ups: Why did the designers of ES Modules choose not to include __dirname and __filename as built-in globals?;How does this same path-resolution need get handled differently again when the code is bundled for a browser environment?