And that's how I feel about package managers. Sure, there are other packages with many of the features of npm, and npm isn't a special snowflake. It could also really do a lot better with handling packages, perhaps with namespacing, and also by adding cryptographic signing capabilities. In my eyes, a large part of the success of Node is due to npm. Perhaps what I like most about npm is how easy it makes publishing packages. For the last, oh, four or five years, I've been a JavaScript programmer. I still write stuff in C in my spare time (I build robots), I spent my 20s writing perl, and the company I work for has a lot of PHP they are converting to Go. But I put food on the table using JavaScript. Incidentally, I tell people asking for my advice about becoming a programmer that if they learn JavaScript and Go they'll never go hungry. The caveat of course is that I'm telling them these things in the same way a bodybuilder tells a fat guy sharing an elevator ride how to get ripped: The conversation is going places reality probably won't follow, so even if it's bad advice, nobody gets hurt. And if you become a JS programmer, you're going to need some thick skin because JavaScript is so popular and ubiquitous, and this has caused tremendous butthurt in the world. But I digress.

The language you use can help or hinder your contributions to open source. JavaScript is helpful in this regard, with Node.js and its package manager, npm.

Let's say we've written a webhook module for a simple monitoring server. All it does is send a simple HTTP request on an event. For our purposes, our webhook module makes a call to Twilio's API when the monitoring server fires a "down server" event. It looks something like this:

module.exports = exports = __notify = (function() {
  var buffer = require('buffer');
  var https = require('https');
  var _down = function( config, server ) {
    // uh oh! server down! let's notify via Twilio's API
    var body = 'To=5125551212';
      body += '&From=+18005551212';
      body += '&Body=Server down (' + server.name + ')';
    var length = Buffer.byteLength(body);
    var options = {
      headers: {
        'Authorization': 'Basic ' + new Buffer(config.account + ':' + config.secret).toString('base64'),
        'Content-Length': length
      },
      hostname: 'api.twilio.com',
      port: 443,
      path: '/2010-04-01/Accounts/' + config.account + '/Messages.json',
      method: 'POST'
    };
    var req = https.request(options, function(res) {
      if (res.statusCode === 200) {
        console.log('Server down: Admin notified!');
      } else {
        console.log('Received strange response from API: ' + res.statusCode);
      }
    });
    req.on('error', function(e) {
      console.log('Error sending request: ' + e.message);
    });
    req.write( encodeURIComponent(body) );
  };
  return { down: _down };
})();

Our particular module isn't very amazing, but it gets the job done. It's also potentially a pretty versatile piece of code: With a little more work, we could make an entire webhook notifier library, with bindings for a few different notification APIs, for example AWS SNS and Sendgrid. I'm only mentioning these companies because I've used them in the past, but they're solid if you're looking for providers.

We've provided some utility and, in addition to creating a repository on Github and pushing our working code, we want to publish this as an npm package. This way anyone wanting to use our module can simply npm install fancynotify and use the module with a quick require(). This sounds like a lot of work, but on the contrary, this is where npm really shines.

First, we'll cd into the root directory of our project. Then, simply execute npm init and answer a few questions to generate a package.json file which we can use. Add and commit this file and any changes. When creating and publishing packages with npm, it is customary to tag a repository with its latest release version. We can do that with git tag -a v0.0.1 -m "v0.0.1: initial release". Now push your tags to Github with git push --tags origin master.

Now we're ready to interact with npm. Run npm adduser from your project's directory. You'll be prompted for a username, password, and email address. Once finished, npm will have created a config file in your home directory (~/.npmrc) which is used for interacting with npm, for example when you release a new version of your package. You can also check this file if you need a hint for your npm login details.

Finally, run npm publish and we're done. Congrats! You've just published a package with npm.