If you’ve ever seen the error __dirname is not defined in ES module scope
, you’re not alone. This common mistake catches many developers off guard—especially when switching from CommonJS to ES Modules in Node.js or working with frameworks like React and Vite.
In this guide, you’ll learn exactly what this error means, why it happens, and how to fix it across different environments like Node.js, React, TypeScript, and even Vite.
What Does “__dirname is Not Defined in ES Module Scope” Mean?
The __dirname
variable in Node.js traditionally gives you the absolute path of the current module. It works perfectly in CommonJS modules, which most developers have used for years.
But in ES Module environments (enabled by setting "type": "module"
in your package.json
or using .mjs
files), __dirname
is not available by default. That’s why you see the error:ReferenceError: __dirname is not defined in ES module scope
Why This Error Happens in Node.js
Node.js supports both CommonJS and ES Modules, but they behave differently. In ES Modules:
__dirname
and__filename
are not defined- You must use
import.meta.url
to get the file path - You can then convert it into a proper directory path using the
path
module
Example Fix:
jsCopyEditimport { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Fixing “__dirname is Not Defined in ES Module Scope”
To fix this error, just follow these steps:
- Use
import.meta.url
to access the module URL - Convert it using
fileURLToPath()
from theurl
module - Use
path.dirname()
to get the directory path
This solution works in:
- ES Modules (
.mjs
or"type": "module"
) - Node.js 14 and above
Handling __dirname
in React and Vite Projects
If you’re working with React or Vite, especially in frontend environments, you might also run into similar path issues.
React:
In a frontend React app, you usually don’t need __dirname
. Instead, use environment variables like process.env.PUBLIC_URL
or absolute imports.
Vite:
Vite is an ES Module-first tool. Instead of __dirname
, use import.meta.url
or Vite’s built-in import.meta.env
.
__dirname is not defined in es module scope react
__dirname is not defined in es module scope vite
TypeScript: Dealing With ReferenceError
When using ES modules in TypeScript, you’ll run into this error too:ReferenceError: __dirname is not defined in ES module scope typescript
✅ Solution:
tsCopyEditimport { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
You may also need to configure your tsconfig.json
to use "module": "ESNext"
or "module": "NodeNext"
.
Common Confusion: require is Not Defined in ES Module Scope
Many devs also see:ReferenceError: require is not defined in ES module scope
Why?
Because require()
is part of CommonJS. In ES modules, you must use import
instead.
Fix:
jsCopyEdit// Wrong in ESM
const fs = require('fs');
// Correct
import fs from 'fs';
Keyword used: require is not defined in es module scope, you can use import instead
Is This a Java Issue Too?
Some developers from Java or backend backgrounds may search this by mistake:
__dirname is not defined in es module scope java
🧠 Note: Java doesn’t use __dirname
or Node.js modules, so this error doesn’t apply to Java. It’s a Node.js-specific concept.
Best Practices to Avoid This Error
- ✅ Always check if you’re using ES Modules (
type: "module"
inpackage.json
) - ✅ Replace
__dirname
with theimport.meta.url
pattern - ✅ Use
path
andurl
modules correctly - ✅ Don’t use
require()
in ESM; switch toimport
FAQs
Q: Can I just switch back to CommonJS?
A: Yes, if you’re not using features exclusive to ES Modules, CommonJS (type: "commonjs"
) is still valid.
Q: How do I know if I’m in ES module scope?
A: Check if you’re using .mjs
files or "type": "module"
in package.json
.
Q: Is this fix future-proof?
A: Yes, the import.meta.url
solution is the recommended approach for working with paths in ES Modules.
Conclusion
The error __dirname is not defined in ES module scope
is frustrating but easy to fix once you understand the cause. Whether you’re working in Node.js, React, Vite, or TypeScript, using import.meta.url
and converting it properly gives you full control over file and directory paths.
Keep experimenting, and remember—every error is just a step closer to mastering JavaScript modules!