How to fix ReferenceError: __filename is not defined in ES module scope in Node.js
This error occurs when trying to use the CommonJS global __filename in an ES module. ES modules use a different approach to access file paths and do not provide __filename by default.
Quick fix
Fixes ERR_REFERENCE_ERROR
{
"type": "module"
}- Verify you're using ES modules
- Use import.meta.filename for Node.js 20.11.0+
- Use fileURLToPath for older Node.js versions
- Create a reusable utility module
{"type": "module"}ReferenceError: __filename is not defined in ES module scope
What this error means
The __filename global variable is a CommonJS feature that provides the absolute path of the currently executing file. When Node.js runs in ES module mode (either through "type": "module" in package.json or using .mjs file extensions), these CommonJS globals are not available. This is by design - ES modules follow the ECMAScript specification which doesn't include these Node.js-specific globals, aiming for better compatibility with browser environments and standardized JavaScript. The error occurs when your code attempts to reference __filename in an ES module context.
Typical symptoms
- ReferenceError thrown when running Node.js scripts with ES module syntax
- Error specifically mentions 'not defined in ES module scope'
- Package.json contains "type": "module" or file has .mjs extension
- Code using import/export statements instead of require()
- Build or runtime failures in projects migrating from CommonJS to ES modules
Common causes
- Project configured to use ES modules via "type": "module" in package.json
- Using .mjs file extension which forces ES module behavior
- Code written for CommonJS not updated when migrating to ES modules
- Third-party packages or dependencies using __filename in ES module context
- Misunderstanding the differences between CommonJS and ES module globals
How to fix "ReferenceError: __filename is not defined in ES module scope"
Check your package.json for "type": "module" or verify your file has a .mjs extension:
{
"type": "module"
}If you see this, you're in ES module mode and need to use the ES module alternatives.
If you're running Node.js version 20.11.0 or higher, you can use the modern built-in properties:
console.log(import.meta.filename); // Current file path
console.log(import.meta.dirname); // Current directory pathThis is the simplest and recommended approach for modern Node.js versions. Check your version with node --version.
For Node.js versions before 20.11.0, manually create __filename and __dirname using import.meta.url:
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Now you can use __filename and __dirname as before
console.log(__filename);
console.log(__dirname);This replicates the CommonJS behavior in ES modules.
If you need __filename/__dirname across many files, create a shared utility:
// utils/paths.js
import path from 'path';
import { fileURLToPath } from 'url';
export function getDirname(importMetaUrl) {
const __filename = fileURLToPath(importMetaUrl);
return path.dirname(__filename);
}
export function getFilename(importMetaUrl) {
return fileURLToPath(importMetaUrl);
}Then use it in your files:
import { getDirname, getFilename } from './utils/paths.js';
const __dirname = getDirname(import.meta.url);
const __filename = getFilename(import.meta.url);If you don't need ES modules, you can switch back to CommonJS:
1. Remove "type": "module" from package.json
2. Rename .mjs files to .js (or use .cjs extension)
3. Replace import/export with require()/module.exports
// CommonJS style
const path = require('path');
console.log(__filename); // Works in CommonJS
console.log(__dirname);Only choose this if you have a specific reason to avoid ES modules.
Advanced notes
Understanding import.meta
The import.meta object is part of the ES module specification and provides metadata about the current module. In Node.js, it includes:
- import.meta.url: File URL of the current module (e.g., "file:///path/to/file.js")
- import.meta.filename: Absolute file path (Node.js 20.11.0+)
- import.meta.dirname: Directory path (Node.js 20.11.0+)
Browser Compatibility Note
The import.meta.filename and import.meta.dirname properties only work when the URL scheme is "file:", so they're not available in browser environments. If you're writing code that runs in both Node.js and browsers, avoid using these properties or provide browser-compatible alternatives.
TypeScript Considerations
If using TypeScript with ES modules, ensure your tsconfig.json has:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node"
}
}TypeScript will properly recognize import.meta properties when configured for ES modules.
Related CommonJS Globals
Other CommonJS globals not available in ES modules include:
- __dirname: Use the same solutions as __filename
- require: Use dynamic import() instead
- require.resolve: Use import.meta.resolve() (Node.js 20.6.0+)
- module, exports: Use ES module export syntax
Frequently asked questions
- What does "ERR_REFERENCE_ERROR" mean?
- The __filename global variable is a CommonJS feature that provides the absolute path of the currently executing file. mjs file extensions), these CommonJS globals are not available. js-specific globals, aiming for better compatibility with browser environments and standardized JavaScript.
- How do I fix "ERR_REFERENCE_ERROR"?
- This error occurs when trying to use the CommonJS global __filename in an ES module. ES modules use a different approach to access file paths and do not provide __filename by default.
- What causes "ERR_REFERENCE_ERROR"?
- Project configured to use ES modules via "type": "module" in package.json Using .mjs file extension which forces ES module behavior Code written for CommonJS not updated when migrating to ES modules
- Is the "ERR_REFERENCE_ERROR" 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 official ES modules documentation(Official Docs)