npm 1.0: The New 'ls'

by Isaac Schlueter,

This is the first in a series of hopefully more than 1 posts, each detailing some aspect of npm 1.0.

In npm 0.x, the ls command was a combination of both searching the registry as well as reporting on what you have installed.

As the registry has grown in size, this has gotten unwieldy. Also, since npm 1.0 manages dependencies differently, nesting them in node_modules folder and installing locally by default, there are different things that you want to view.

The functionality of the ls command was split into two different parts. search is now the way to find things on the registry (and it only reports one line per package, instead of one line per version), and ls shows a tree view of the packages that are installed locally.

Here’s an example of the output:

$ npm ls
[email protected] /Users/isaacs/dev-src/js/npm
├── [email protected] 
├─┬ [email protected] 
│ └── [email protected] 
└─┬ [email protected] extraneous 
  ├─┬ [email protected] 
  │ ├── [email protected] 
  │ └── [email protected] 
  ├── [email protected] 
  └── [email protected]

This is after I’ve done npm install semver ronn express in the npm source directory. Since express isn’t actually a dependency of npm, it shows up with that “extraneous” marker.

Let’s see what happens when we create a broken situation:

$ rm -rf ./node_modules/express/node_modules/connect
$ npm ls
[email protected] /Users/isaacs/dev-src/js/npm
├── [email protected] 
├─┬ [email protected] 
│ └── [email protected] 
└─┬ [email protected] extraneous 
  ├── UNMET DEPENDENCY connect >= 1.1.0 < 2.0.0
  ├── [email protected] 
  └── [email protected]

Tree views are great for human readability, but some times you want to pipe that stuff to another program. For that output, I took the same datastructure, but instead of building up a treeview string for each line, it spits out just the folders like this:

$ npm ls -p

Since you sometimes want a bigger view, I added the --long option to (shorthand: -l) to spit out more info:

$ npm ls -l
[email protected] 
│ /Users/isaacs/dev-src/js/npm
│ A package manager for node
│ git://
├── [email protected] 
│   ./node_modules/semver
│   The semantic version parser used by npm.
│   git://
├─┬ [email protected] 
│ │ ./node_modules/ronn
│ │ markdown to roff and html converter
│ └── [email protected] 
│     ./node_modules/ronn/node_modules/opts
│     Command line argument parser written in the style of commonjs. To be used with node.js
└─┬ [email protected] extraneous 
  │ ./node_modules/express
  │ Sinatra inspired web development framework
  ├─┬ [email protected] 
  │ │ ./node_modules/express/node_modules/connect
  │ │ High performance middleware framework
  │ │ git://
  │ ├── [email protected] 
  │ │   ./node_modules/express/node_modules/connect/node_modules/qs
  │ │   querystring parser
  │ └── [email protected] 
  │     ./node_modules/express/node_modules/connect/node_modules/mime
  │     A comprehensive library for mime-type mapping
  ├── [email protected] 
  │   ./node_modules/express/node_modules/mime
  │   A comprehensive library for mime-type mapping
  └── [email protected] 
      querystring parser

$ npm ls -lp
/Users/isaacs/dev-src/js/npm:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/semver:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/ronn:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/ronn/node_modules/opts:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/express:[email protected]:EXTRANEOUS:::
/Users/isaacs/dev-src/js/npm/node_modules/express/node_modules/connect:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/express/node_modules/connect/node_modules/qs:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/express/node_modules/connect/node_modules/mime:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/express/node_modules/mime:[email protected]::::
/Users/isaacs/dev-src/js/npm/node_modules/express/node_modules/qs:[email protected]::::

And, if you want to get at the globally-installed modules, you can use ls with the global flag:

$ npm ls -g
├─┬ [email protected] -> /Users/isaacs/dev-src/js/A
│ ├── [email protected] -> /Users/isaacs/dev-src/js/B
│ └─┬ [email protected] 
│   └── [email protected] 
├─┬ [email protected] -> /Users/isaacs/dev-src/js/B
│ └── [email protected] -> /Users/isaacs/dev-src/js/A
├── [email protected] 
├─┬ [email protected] -> /Users/isaacs/dev-src/js/npm
│ ├── [email protected] 
│ └─┬ [email protected] 
│   └── [email protected] 
└── [email protected] -> /Users/isaacs/dev-src/js/node-supervisor

$ npm ls -gpl
/usr/local/lib/node_modules/A:[email protected]::::/Users/isaacs/dev-src/js/A
/usr/local/lib/node_modules/A/node_modules/npm:[email protected]::::/Users/isaacs/dev-src/js/A/node_modules/npm
/usr/local/lib/node_modules/A/node_modules/npm/node_modules/semver:[email protected]::::/Users/isaacs/dev-src/js/A/node_modules/npm/node_modules/semver
/usr/local/lib/node_modules/B:[email protected]::::/Users/isaacs/dev-src/js/B
/usr/local/lib/node_modules/glob:[email protected]::::
/usr/local/lib/node_modules/npm:[email protected]::::/Users/isaacs/dev-src/js/npm
/usr/local/lib/node_modules/npm/node_modules/semver:[email protected]::::/Users/isaacs/dev-src/js/npm/node_modules/semver
/usr/local/lib/node_modules/npm/node_modules/ronn:[email protected]::::/Users/isaacs/dev-src/js/npm/node_modules/ronn
/usr/local/lib/node_modules/npm/node_modules/ronn/node_modules/opts:[email protected]::::/Users/isaacs/dev-src/js/npm/node_modules/ronn/node_modules/opts
/usr/local/lib/node_modules/supervisor:[email protected]::::/Users/isaacs/dev-src/js/node-supervisor

Those -> flags are indications that the package is link-installed, which will be covered in the next installment.

Scroll to top