How to fix the “__dirname is not defined in ES module scope” error in JavaScript

The “__dirname is not defined in ES module scope” error happens in JavaScript when we try to access the __dirname global variable in an ES module. The __dirname and __filename global variables are defined in CommonJS modules, but not in ES modules.

The "__dirname is not defined in ES module scope" error occurring in JavaScript.
The “__dirname is not defined in ES module scope” error occurring in JavaScript.

We can fix the “__dirname is not defined in ES module scope” error by using certain functions to create a custom __dirname variable that works just like the global variable, containing the full path of the file’s current working directly.

index.js

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);

const __dirname = path.dirname(__filename);

// C:/cb/cb-js
console.log(__dirname);

// C:\cb\cb-js\index.html
console.log(path.join(__dirname, 'index.html'));

The import.meta object contains context-specific metadata associated with a certain module, e.g., a module’s file URL.

// file:///C:/cb/cb-js/index.js
console.log(import.meta.url);

So we get the current module’s file URL and pass it to the fileURLToPath function from the url module, to convert it to a file path. fileURLToPath returns a fully-resolved, platform-specific Node.js file path.

// C:\cb\cb-js\index.js
console.log(fileURLToPath('file:///C:/cb/cb-js/index.js'));

After getting the file path, we pass it to the dirname method from the path module, to get the full directory path from the file path.

// C:\cb\cb-js
console.log(path.dirname('C:\\cb\\cb-js\\index.js'));

With this, we now have our own __dirname and __filename variables.

Here’s the output from logging them from a file on my computer.

Logging the "__dirname" and "__filename" variables to the console.
Logging the __dirname and __filename variables to the console.

__filename contains the absolute path of the current module file.

__dirname contains the absolute path of the current module file’s directory.

Create utility for __dirname and __filename

If we access the __dirname and __filename variables frequently, we can abstract the logic for creating them in a utility module and avoid unnecessary repetition.

file-dir-name.js

import { fileURLToPath } from 'url';
import { dirname } from 'path';

export default function fileDirName(meta) {
  const __filename = fileURLToPath(meta.url);

  const __dirname = dirname(__filename);

  return { __dirname, __filename };
}

We’ll be able to use this utility across the various other module files in our project.

index.js

import fileDirName from './file-dir-name.js';

const { __dirname, __filename } = fileDirName(import.meta);

// C:\cb\cb-js
console.log(__dirname);

// C:\cb\cb-js\index.js
console.log(__filename);


Every Crazy Thing JavaScript Does

A captivating guide to the subtle caveats and lesser-known parts of JavaScript.

Every Crazy Thing JavaScript Does

Sign up and receive a free copy immediately.

Leave a Comment

Your email address will not be published. Required fields are marked *