npm package binary directory


TL;DR: process.cwd() will return the directory of the running process; __dirname will return the directory of the actual file.

Motivation

I was working on an npm package executable and I wanted to know the directory of the package as well as the project.

Setup

Create the following directories:

$ mkdir a/ b/

a will contain your app project and b will contain your npm package binary.

Package

Enter directory b:

$ cd b/

Initialize the package.json:

$ npm init -y

Create your script:

$ touch script.js

Add the following code to your script:

#!/usr/bin/env node

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

Set the bin field in package.json:

{
  "name": "b",
  "bin": "script.js"
}

Symlink your package:

$ npm link

/usr/local/bin/b -> /usr/local/lib/node_modules/b/script.js
/usr/local/lib/node_modules/b -> /Users/remarkablemark/b

Project

Enter directory a:

$ cd ../a/

Install b as a symlink:

$ npm link b
/Users/remarkablemark/a/node_modules/b -> /usr/local/lib/node_modules/b -> /Users/remarkablemark/b

When you execute the binary:

$ npx b # yarn b

You’ll get the output:

process.cwd(): /Users/remarkablemark/a
__dirname: /Users/remarkablemark/b
__filename: /Users/remarkablemark/b/script.js
process.mainModule: Module {
  id: '.',
  path: '/Users/remarkablemark/b',
  exports: {},
  parent: null,
  filename: '/Users/remarkablemark/b/script.js',
  loaded: false,
  children: [],
  paths: [
    '/Users/remarkablemark/b/node_modules',
    '/Users/remarkablemark/node_modules',
    '/Users/node_modules',
    '/node_modules'
  ]
}

Conclusion

By executing binary b in directory a (via npm, npx, or yarn):

In other words, process.cwd() will return the root directory of the app, whereas __dirname will return the directory of the binary file.



If you enjoyed this post, please consider supporting this site!