Why did __dirname disappear?If you've recently swapped require for import in your Node.js project, you likely hit a wall. You try to access the current directory, and Node.js throws a ReferenceError. This happens because ES Modules (ESM) don't include global variables like __dirname or __filename by default.
CommonJS provides these variables automatically. However, ESM was designed to be platform-agnostic. Since a browser doesn't have a "directory structure" in the same way a server does, these globals were removed to keep ESM consistent across different environments. If you are running Node.js 14 or newer, you'll need to reconstruct these paths manually.
The Solution: Use import.meta.urlTo get your paths back, you need to use import.meta.url. This property gives you the full URL of the current module, such as file:///Users/dev/project/index.js. We can then convert this URL into a standard file path using Node's built-in utilities.
1. Import the path and url modulesStart by bringing in the tools needed to handle file URLs and path strings. Add these lines to the top of your script:
import { fileURLToPath } from 'url';
import { dirname } from 'path';
2. Recreate the missing globalsYou can define __filename and __dirname manually with just two lines of code. This makes your ESM code feel familiar again.
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
3. Putting it all togetherHere is how a typical setup looks when you need to locate a config folder relative to your script:
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Example: Joining paths for a settings file
const configPath = path.join(__dirname, 'config', 'settings.json');
console.log(`Target path: ${configPath}`);
Testing the FixVerify the solution by creating a file named app.mjs (or app.js if your package.json has "type": "module"). Paste the logic above and run it:
node app.mjs
Your terminal should now print the absolute path to your file and folder. No more ReferenceErrors.
Pro-Tips for ESM File Paths### Don't rely solely on process.cwd()It is tempting to use process.cwd() as a shortcut. Be careful: process.cwd() returns the directory where you started the terminal command, not where the script lives. If you run node ./src/app.js from the root folder, process.cwd() and __dirname will point to different places.
Loading JSON files safelyMost developers need __dirname to read JSON files. While modern Node.js versions (v20.10+) support Import Attributes for JSON, the fs module combined with our __dirname fix remains the most compatible method for older LTS versions:
import { readFileSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rawData = readFileSync(path.join(__dirname, 'data.json'), 'utf8');
const data = JSON.parse(rawData);

