__filename vs __dirname vs process.cwd()

__dirname and process.cwd() are often used in the same context. Sometimes they can be used for each other, other times they can't. This can lead to confusion about their meanings. In this post, I will discuss how and why they are different.

Before we dive into the nuances of __dirname, __filename and process.cwd, let’s briefly talk about how Node.js creates modules.

The Node.js module system

In Node.js, each file is treated as a module and we need to explicitly export what we want to use outside of that module (file).

The exported piece of code which can be an object, function or even a class may then be required in other modules of the application.

Before the code we require is executed, Node.js wraps all of it in a function:

(function(exports, require, module, __filename, __dirname) {
  // module code
});

This is why the variables we define with const and let in the module will stay private (they will remain inside the wrapper function’s scope) and the arguments of the wrapper function (including __dirname and __filename) will be local variables belonging to that module.

__dirname

__dirname is a string and displays the directory name of the current folder. It can be used and logged as is:

console.log(__dirname); // DIRECTORY_NAME_WITH_PATH

__dirname seems to be part of the global object but - as we have seen - it’s local and is specific to the given module!

__filename

__filename is also a string and is the name of the current module (which is a file):

console.log(__filename); // FILE_NAME_WITH_PATH

Similarly to __dirname, __filename can be used as is and it exists in the module.

process.cwd()

process.cwd() returns the current working directory of the Node.js process that is running - hence the name of the method:

console.log(process.cwd()); // DIRECTORY_NAME_OF_THE_PROCESS_WITH_PATH

This method is the odd-one-out as process.cwd() lives in the process module and not in the exported module itself. The process object is a global and as such, it can be used without require-ing it.

Example

It’s common that __dirname is confused with process.cwd(). The main difference is that __dirname is related to the module (see the wrapper function above) and process.cwd() refers to the running process regardless of where it’s called.

In order to see the difference, we can create two files and a folder.

Let the name of the folder be dependencies and it contains a file called dependency.js. We will require this module in the other file called main.js, which is in the root folder.

So the folder structure can look like this:

|--- dependencies
|       dependency.js
|--- main.js

dependency.js contains a function that logs the dependency.js-related __dirname and __filename and we call process.cwd() as well:

// dependencies/dependency.js

const logNames = () => {
  console.log('from dependency, __dirname:', __dirname);
  console.log('from dependency, __filename:', __filename);
  console.log('from dependency, process.cwd():', process.cwd());
}

module.exports = logNames;

We export logNames because it will be used in main.js, which can look like this:

// main.js

const logNames = require('./dependency/dependency');

console.log('from main, __dirname:', __dirname);
console.log('from main, __filename:', __filename);
console.log('from main, process.cwd():', process.cwd());

logNames();

We require the exported function here, log __dirname and __filename (they are specific to main.js) as well as the returned value of process.cwd(), and then call logNames.

Let’s now run main.js with the node main.js command.

We should get something similar in the console:

from main, __dirname: PATH_TO_THE_PROJECT_ROOT
from main, __filename: PATH_TO_THE_PROJECT_ROOT/main.js
from main, process.cwd(): PATH_TO_THE_PROJECT_ROOT
from dependency, __dirname: PATH_TO_THE_PROJECT_ROOT/dependency
from dependency, __filename: PATH_TO_THE_PROJECT_ROOT/dependency/dependency.js
from dependency, process.cwd(): PATH_TO_THE_PROJECT_ROOT

Both __dirname and __filename is specific the module they live in, therefore they return the relevant directory and file names of their modules.

But process.cwd() returns the directory name of the current running process. Because we started the process by running the code inside main.js, and main.js is located in the root folder, process.cwd() will return the path to the root.

We required dependency.js in main.js and because logNames, which was defined in another module (dependency.js), was called in main.js, the returned values will be the same in both cases.

Conclusion

It’s easy to confuse __dirname and process.cwd(). The key difference is that __dirname is specific to the given module (file), while process.cwd() is a method of the global process object returning the directory name of the file from where the process was run.

__filename is the little brother of __dirname with a difference of showing the name of the file instead of the folder name.

I hope that the post was helpful. Thanks for reading and see you next time.