Get the current module’s path in Node.js
Use CommonJS filename variables or ES module metadata, and distinguish a module’s location from the process working directory.
In CommonJS, __filename identifies the current module file and __dirname its directory. In an ES module, use import.meta.url, or the newer import.meta.filename and import.meta.dirname where your supported Node version provides them.
Use CommonJS variables
In a .cjs file:
const path = require('node:path');
console.log(__filename);
console.log(__dirname);
const configPath = path.join(__dirname, 'config.json');
These variables refer to the current module, which may be a dependency rather than the program's entry file. Building the path from __dirname avoids interpreting config.json relative to whichever directory launched the process.
Use ES module metadata
A broadly compatible ES module pattern is:
import { fileURLToPath } from 'node:url';
import path from 'node:path';
const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);
console.log(filename, dirname);
Use fileURLToPath() instead of reading the URL's pathname as a native path. It handles percent encoding and platform-specific path forms, including Windows drive letters and network paths.
Node 20.11.0 and 21.2.0 added import.meta.filename and import.meta.dirname; they became non-experimental in 22.16.0 and 24.0.0. They are available for local file: modules, not every possible module URL. On a suitable release:
console.log(import.meta.filename);
console.log(import.meta.dirname);
Many filesystem APIs also accept a file URL directly:
import { readFile } from 'node:fs/promises';
const config = await readFile(new URL('./config.json', import.meta.url), 'utf8');
This example expects an actual adjacent config.json file.
Keep the base directory explicit
| Value or operation | Base or meaning |
|---|---|
__dirname |
Current CommonJS module's directory |
import.meta.url |
Current ES module's URL |
process.cwd() |
Process working directory; can change through process.chdir() |
require('./data.json') |
Resolution relative to the requiring module |
fs.readFile('./data.json') |
Filesystem lookup relative to the working directory |
Module-relative resources and user-supplied relative paths may intentionally use different bases. Choose the one the application requires.
FAQ
What happens after bundling? Bundler settings may preserve, replace, or emulate these values. They do not universally point to the original source directory. Decide whether resources should be bundled, copied next to output, or located through configuration, then test the built artifact.
Does dirname end with a separator? Ordinary directory paths usually do not, but a filesystem root is a relevant exception. Use path.join() rather than relying on string concatenation rules.
What path appears in a container? The module path is expressed in the container's filesystem namespace. A host bind mount does not make it a host-native path. __filename is a file path; __dirname is its containing directory.
What about symlinks? Resolution depends on the module-loading mode and relevant Node flags. The newer ES module filename metadata documents resolved symlinks. If the invocation path of a symlink matters, treat that as a separate requirement from finding the loaded module.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan