TL;DR: How lazy can you be? This post should take you 5 minutes to read... :-P

So npm is out of Debian testing. This means that the hell that is node code handling is now even harder. node's installation instructions is a bloody video from which you can't copy and paste the commands (how useful), and as far as I can tell, it's the official way to install npm.

If you already have a good version of node provided by your trusted distribution, you most probably will cringe on the idea of installing a third party package like this, and probably you don't think containers are the solution, or you just want to install something locally so you can play with it.

If you look closer to the bottom of that page you'll find the "advances user's" guide to install it yourself, but it's only a pattern URL to the distribution .tar.gz, with no further instructions. With a little bit of luck, the instructions will be included. The pattern has a placeholder for the version you want (putatively, the latest), but I can't find, for the life of me, references to which is the latest version.

In the GitHub project page you will find the terrible, unluckily classic curl | sh command that downloads this script. The script is in POSIX shell dialect, and has strange constructions:

node=`which node 2>&1`
if [ $ret -eq 0 ] && [ -x "$node" ]; then
  (exit 0)

To me, that exit 0 in a subshell is the equivalent of a NOOP, so I wonder why they decided to write the condition like that.

After checking the availability of a couple of tools (node, tar, make, but not curl), it uses the latter to download JSON from the registry, finding there the actual version (currently 4.5.0, if you're interested). It downloads the package, untars it, and executes:

"$node" cli.js rm npm -gf
"$node" cli.js install -gf

The first removes any old installation. More on that in a minute. The second, obviously, installs the new version. But the -gf options (I hate short options in scripts) are to be guessed, as no help is provided about them. Let's go with --global and --force, which means it will install somewhere in your system and overwriting anything it finds. With the previous command it should have deleted all the files (same options), so you're really nuking whatever was there before.

Nowhere in the instructions so far says anything about root, but obviously this needs to be run as such. There's also this detail:

As of version 0.3, it is recommended to run npm as root. This allows npm to
change the user identifier to the nobody user prior to running any package
build or test commands.

So there's no way to make a local installation of npm... is there? Well, not user wide, only system wide (already explained) and project wide. Here's how to do the latter:

$ wget
$ tar xvf npm-4.5.0.tgz  # it's unpacked in a directory called 'package'
$ /usr/bin/node package/cli.js install npm
$ rm -rf package  # clean up after you!
$ ./node_modules/.bin/npm install carto

The third command uses the tarball's CLI interface to install the same version 'the right way'. To be honest, I had already used the old npm version that used to come with Debian to do exactly the same thing. Of course, this works as long as newer version of npm can still be installed with such an old version of the same. Who knows when that's gonna break/be deprecated.

All in all, it's sad to see such an useful tool be dropped like that. I just hope someone can pick up the pieces.

debian nodejs npm