How to get the current folder in Node
By Flavio Copes
Learn how to get the current folder in Node.js and understand the difference between ./, __dirname, import.meta.dirname, and process.cwd() when referencing the filesystem.
There are a few ways to reference the current folder in a Node.js script:
./__dirname(CommonJS)import.meta.dirname(ES modules)
Along with
./, there is../, which points to the parent folder. They behave in the same way.
There is a big difference between the file’s folder and the working directory, and picking the wrong one is a classic source of “file not found” errors.
What does each one return?
Using __dirname in a CommonJS script will return the path of the folder where the current JavaScript file resides.
Using ./ will give you the current working directory. It will return the same result as calling process.cwd().
Say you have a script at /Users/flavio/dev/app/src/index.js, and you run it from the app folder:
cd /Users/flavio/dev/app
node src/index.js
Inside the script:
console.log(__dirname)
///Users/flavio/dev/app/src
console.log(process.cwd())
///Users/flavio/dev/app
__dirname never changes. It’s tied to the file. The working directory instead depends on where you ran the node command from.
Initially the current working directory is the path of the folder where you ran the node command, but that can be changed during the execution of your script, by using the process.chdir() API.
ES modules: import.meta.dirname
In an ES module (a .mjs file, or a .js file in a package with "type": "module"), __dirname is not defined.
Node gives you import.meta.dirname as the equivalent. It arrived in Node 20.11 and became stable in Node 24:
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
const data = await readFile(
join(import.meta.dirname, 'config.json'),
'utf8'
)
On an older Node without import.meta.dirname, build it from the file URL:
import { readFile } from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const data = await readFile(join(__dirname, 'config.json'), 'utf8')
Same idea as CommonJS __dirname: the folder of the current file, not the working directory.
A pitfall with relative paths
Here’s where this bites you. Suppose index.js reads a file sitting next to it:
const data = fs.readFileSync('./config.json', 'utf8')
This works when you run node index.js from inside src. Run it from anywhere else, and Node looks for config.json in your working directory instead, and throws ENOENT: no such file or directory.
The fix is to build the path from __dirname (or import.meta.dirname in ESM), so it works no matter where the script is launched from:
const path = require('path')
const data = fs.readFileSync(path.join(__dirname, 'config.json'), 'utf8')
My advice: any time a script needs a file relative to itself, use __dirname or import.meta.dirname. Use the working directory only when you want to act on the folder the user is in, like a CLI tool does.
The require() exception
There is just one place where ./ refers to the current file path, and it’s in a require() call. In there, ./ (for convenience) will always refer to the JavaScript file path, letting you import other modules based on the folder structure.
Want me to talk about your product? You can sponsor this site.
Related posts about node: