How to fix ReferenceError: __dirname is not defined in ES module scope in Node.js

Node.jsINTERMEDIATEMEDIUMUpdated Dec 9, 2025ยท 169 views

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');
  1. Use import.meta.dirname for Node.js 20.11.0+
  2. Use fileURLToPath with import.meta.url for older versions
  3. Create a reusable utility for path resolution
  4. Convert ES module back to CommonJS if needed
node.js โ€” error
// 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');
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

  1. Using __dirname or __filename in a file with .mjs extension
  2. Project package.json has 'type: module' set and code uses __dirname
  3. Migrating from CommonJS to ES modules without updating path resolution
  4. Copying CommonJS code examples into an ES module project
  5. TypeScript compiling to ES modules but using CommonJS-style path operations

How to fix "ReferenceError: __dirname is not defined in ES module scope"

1Use import.meta.dirname for Node.js 20.11.0+

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:

javascript
// 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.

2Use fileURLToPath with import.meta.url for older versions

For Node.js versions before 20.11.0, manually recreate __dirname and __filename using the url and path modules:

javascript
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.js

Place 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.

3Create a reusable utility for path resolution

If you frequently need to resolve paths relative to module files, create a utility function:

javascript
// 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:

javascript
// 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');
4Convert ES module back to CommonJS if needed

If you're not ready to use ES modules or encounter compatibility issues, revert to CommonJS. Remove or change "type": "module" in package.json:

json
{
  "type": "commonjs"
}

Or simply omit the "type" field (CommonJS is the default). Then change your imports to requires:

javascript
// 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:

javascript
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