How to fix ReferenceError: __dirname is not defined in ES module scope in Node.js
This error occurs when attempting to use __dirname or __filename in ES modules. These CommonJS globals are not available in ES module scope, requiring alternative approaches using import.meta.url or the newer import.meta.dirname.
Quick fix
Fixes ReferenceError: __dirname is not defined in ES module scope
// Get the directory name (replaces __dirname)
console.log(import.meta.dirname);
// Output: /home/user/project/src
// Get the file name (replaces __filename)
console.log(import.meta.filename);
// Output: /home/user/project/src/index.js
// Use in path operations
import { join } from 'path';
const configPath = join(import.meta.dirname, 'config.json');- Use import.meta.dirname for Node.js 20.11.0+
- Use fileURLToPath with import.meta.url for older versions
- Create a reusable utility for path resolution
- Convert ES module back to CommonJS if needed
// Get the directory name (replaces __dirname)console.log(import.meta.dirname);// Output: /home/user/project/src// Get the file name (replaces __filename)console.log(import.meta.filename);// Output: /home/user/project/src/index.js// Use in path operationsimport { join } from 'path';const configPath = join(import.meta.dirname, 'config.json');ReferenceError: __dirname is not defined in ES module scope
What this error means
The "__dirname is not defined" error occurs because __dirname and __filename are CommonJS-specific globals that are not included in the ECMAScript module specification. When you use ES modules (identified by "type": "module" in package.json or .mjs file extensions), Node.js does not automatically provide these variables. This design decision was intentional. ES modules were created to work in both browser and server environments. Since browsers don't have file system access, providing directory path globals wouldn't make sense in that context. To maintain consistency across environments, the ES module specification omitted these Node.js-specific variables. Instead, ES modules provide import.meta.url, which contains the file URL of the current module. This can be converted to a file path and directory path using Node.js utilities, or in modern Node.js versions (20.11.0+), you can use the built-in import.meta.dirname and import.meta.filename properties directly.
Typical symptoms
- ReferenceError when trying to access __dirname or __filename
- Error message specifically mentions 'ES module scope'
- Code runs fine in CommonJS but breaks when switching to ES modules
- Error occurs after adding 'type: module' to package.json
- File paths cannot be resolved relative to the current module
Common causes
- Using __dirname or __filename in a file with .mjs extension
- Project package.json has 'type: module' set and code uses __dirname
- Migrating from CommonJS to ES modules without updating path resolution
- Copying CommonJS code examples into an ES module project
- TypeScript compiling to ES modules but using CommonJS-style path operations
How to fix "ReferenceError: __dirname is not defined in ES module scope"
If you're using Node.js version 20.11.0 or newer, you can use the built-in import.meta.dirname and import.meta.filename properties:
// Get the directory name (replaces __dirname)
console.log(import.meta.dirname);
// Output: /home/user/project/src
// Get the file name (replaces __filename)
console.log(import.meta.filename);
// Output: /home/user/project/src/index.js
// Use in path operations
import { join } from 'path';
const configPath = join(import.meta.dirname, 'config.json');Check your Node.js version with node --version. This is the cleanest and most modern solution requiring no imports or utility functions.
For Node.js versions before 20.11.0, manually recreate __dirname and __filename using the url and path modules:
import { fileURLToPath } from 'url';
import { dirname } from 'path';
// Convert import.meta.url to a file path
const __filename = fileURLToPath(import.meta.url);
// Get the directory name
const __dirname = dirname(__filename);
console.log(__dirname); // /home/user/project/src
console.log(__filename); // /home/user/project/src/index.jsPlace this code at the top of any module where you need __dirname. You can also create a utility file that exports these values if you need them in multiple modules.
If you frequently need to resolve paths relative to module files, create a utility function:
// utils/paths.js
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
export function getDirname(importMetaUrl) {
const __filename = fileURLToPath(importMetaUrl);
return dirname(__filename);
}
export function resolveFromModule(importMetaUrl, ...paths) {
const dir = getDirname(importMetaUrl);
return join(dir, ...paths);
}Then use it in your modules:
// src/index.js
import { resolveFromModule } from './utils/paths.js';
const configPath = resolveFromModule(import.meta.url, '../config/app.json');
const dataPath = resolveFromModule(import.meta.url, 'data', 'users.db');If you're not ready to use ES modules or encounter compatibility issues, revert to CommonJS. Remove or change "type": "module" in package.json:
{
"type": "commonjs"
}Or simply omit the "type" field (CommonJS is the default). Then change your imports to requires:
// ES module syntax
import fs from 'fs';
import path from 'path';
// CommonJS syntax
const fs = require('fs');
const path = require('path');Rename .mjs files to .js if applicable. With CommonJS, __dirname and __filename will work normally. However, note that ES modules are the future standard and offer better tree-shaking and static analysis benefits.
Advanced notes
TypeScript configuration: When using TypeScript with ES modules, ensure your tsconfig.json has "module": "ESNext" or "module": "ES2022" and "moduleResolution": "node16" or "bundler". If you target older Node.js versions, you'll need to include the fileURLToPath workaround in your source code before compilation.
URL vs file paths: import.meta.url returns a file:// URL (like file:///home/user/project/file.js), not a file path. Always use fileURLToPath() to convert it before passing to file system operations or path utilities. Directly using the URL string can cause issues on Windows.
Directory detection alternative: You can get the directory path directly without creating __filename first:
import { fileURLToPath } from 'url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));The '.' in new URL('.', import.meta.url) resolves to the directory containing the current module.
Bundler considerations: If you're using bundlers like webpack, esbuild, or Rollup, they may handle import.meta.url differently or provide their own globals. Check your bundler's documentation for the recommended approach.
Mixed CommonJS/ESM projects: In projects using both module systems, consider creating wrapper utilities that detect the module type and provide unified path resolution. Some packages like node:path work identically in both contexts, but global availability differs.
Frequently asked questions
- What does "ReferenceError: __dirname is not defined in ES module scope" mean?
- The "__dirname is not defined" error occurs because __dirname and __filename are CommonJS-specific globals that are not included in the ECMAScript module specification. js does not automatically provide these variables. This design decision was intentional.
- How do I fix "ReferenceError: __dirname is not defined in ES module scope"?
- This error occurs when attempting to use __dirname or __filename in ES modules. These CommonJS globals are not available in ES module scope, requiring alternative approaches using import.meta.url or the newer import.meta.dirname.
- What causes "ReferenceError: __dirname is not defined in ES module scope"?
- Using __dirname or __filename in a file with .mjs extension Project package.json has 'type: module' set and code uses __dirname Migrating from CommonJS to ES modules without updating path resolution
- Is the "ReferenceError: __dirname is not defined in ES module scope" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐Node.js ECMAScript Modules Documentation(Official Docs)
- ๐Node.js import.meta.dirname Documentation(Official Docs)
- ๐Node.js fileURLToPath Documentation(Official Docs)
- ๐
- ๐