When working with Node.js, you might encounter the error: ReferenceError: __dirname is not defined in ES module scope.This usually happens when you switch from CommonJS (require) to ES Modules (import/export). In CommonJS, __dirname and __filename are built-in globals that give you the current file’s directory and path. However, ES Modules don’t provide these by default, leading to confusion for many developers migrating their projects or using modern import syntax.

In this article, we’ll break down why this error occurs, how ES Modules differ from CommonJS, and the best practices to fix or work around the issue in Node.js.

Fix ReferenceError: __dirname is Not Defined in ES Module Scope

CommonJS vs ES Modules in Node.js

When working with Node.js, you’ll often come across two different module systems: CommonJS (CJS) and ECMAScript Modules (ESM). Understanding their differences is key to knowing why __dirname behaves differently.

CommonJS (CJS)

Example:

// CommonJS example
const path = require('path');

console.log(__dirname); // absolute path of the current file’s directory
console.log(__filename); // absolute path of the current file

Here, __dirname always works out of the box because CommonJS injects it into every module.

ES Modules (ESM)

Example:

// ES Module example
import path from 'path';
console.log(__dirname); // ❌ ReferenceError: __dirname is not defined

Since ES Modules are designed to be universal (usable outside of Node.js), Node.js does not include Node-specific globals like __dirname. Instead, you need to rely on import.meta.url and helper functions from the url and path modules to reconstruct similar behavior.

Why ReferenceError: __dirname is Not Defined in ES Module Scope

If you’ve switched from CommonJS to ES Modules, the sudden absence of __dirname can feel confusing. The reason lies in the design philosophy behind ESM.

1. Standardization Across Environments

2. Different Loading Mechanism

3. Encouraging Explicit Path Handling

Rather than relying on injected globals, you construct the path using:

import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

How to Fix: ReferenceError: __dirname is Not Defined in ES Module Scope

Now that we understand why __dirname isn’t available in ES Modules, let’s look at the most common ways to fix it. Depending on your use case, you can choose one of the following solutions:

The modern and most reliable approach is to reconstruct __filename and __dirname using import.meta.url.

// ES Module example
import { fileURLToPath } from 'url';
import { dirname } from 'path';

// Recreate CommonJS globals
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
console.log(__dirname); // Prints current file’s directory
console.log(__filename); // Prints current file path

This method works consistently across Node.js projects using ES Modules and is the closest equivalent to the old CommonJS globals.

Solution 2: Use process.cwd() (Project Root Directory)

If you don’t specifically need the current file’s directory and instead want to work relative to the project root, you can use process.cwd().

console.log(process.cwd()); // Prints the working directory where Node.js was started

This is useful for reading configuration files, logs, or assets located at the root of your project. However, keep in mind that if you run your script from a different folder, the result may change.

Solution 3: Stick with CommonJS

If migrating to ES Modules isn’t required for your project, you can simply keep using CommonJS and continue relying on __dirname as before.

Two ways to do this:

1. Rename your file from .js to .cjs.

Or set your package.json type to CommonJS:

{"type": "commonjs"}

2. Then, your old code will continue working:

const path = require('path');
console.log(__dirname);

Summary of Fixes:

Best Practices

Now that you know the different fixes, it’s important to choose the right one depending on your project needs. Here are some best practices to follow:

1. Prefer import.meta.url for File-Specific Paths

2. Use process.cwd() for Project-Wide Paths

3. Be Consistent Across Your Project

4. Only Use CommonJS if Legacy Support is Required

In short:

Conclusion:  on ReferenceError: __dirname is not defined in ES module scope

The error

ReferenceError: __dirname is not defined in ES module scope

isn’t a bug – it’s a design choice. ES Modules were built to be standard across environments, which means Node.js doesn’t inject Node-specific globals like __dirname.

The good news is that the fix is straightforward:

By understanding the difference between CommonJS and ES Modules, and applying the right solution for your case, you can handle file paths in Node.js confidently – without running into unexpected errors.