Prints a dependency graph of modules that is actually required

npm graph

Essentially npm ls with two modifications:

  • only explicitly required dependencies
  • finds cyclical requires

Dependencies are analyzed using parts of the browserify toolchain.

Install globally and give it a path to a local package or a file:

$ npm install -g npm-graph
$ npm-graph node_modules/irc-stream/

If all modules in "dependencies" are used, then this should look like npm ls.

$ npm-graph node_modules/irc-stream/ -b
 │  ├───net
 │  ├───tls
 │  └───util

This can give some at a glance information about how browserifiable the module is.

File by file inclusion:

$ npm-graph node_modules/irc-stream/ -l

Cycles are detected and shown in the tree with a after an offender. As an example, readable-stream (tsk tsk) closes a cyclical loop by having Duplex depend on Writable and vice versa (albeit lightly).

$ npm install readable-stream@1.0.27-1
$ npm-graph node_modules/readable-stream/writable.js -l
   ├─┬./_stream_duplex ↪ ./_stream_writable
   │ ├─┬./_stream_readable
   │ │ ├──core-util-is
   │ │ ├──inherits
   │ │ ├──isarray
   │ │ └──string_decoder/
   │ ├──core-util-is
   │ └──inherits

The mutual file inclusions would normally cause a recursion overflow when generating the tree if we hadn't first found the strongly connected components in the inclusion digraph and manually broken the cycle.

( •_•)
( •_•)>⌐■-■

The cyclical components from Tarjan's algorithm are also available with -c:

$ npm-graph node_modules/readable-stream/writable.js -l -c
[ [ './node_modules/readable-stream/lib/_stream_writable.js',
    './node_modules/readable-stream/lib/_stream_duplex.js' ] ]

In this case, a 2-cycle.

MIT-Licensed. See LICENSE file for details.