Publishing Your First Package to npm

May 19, 2016

npm, a.k.a. the Node Package Manager, is a developer-friendly command-line package manager included with Node.js. It makes it super-easy to install other people's JavaScript packages to extend your projects as well as publish your own JavaScript code with the world.

That exciting feeling you get when you publish an open-source project on GitHub? This one's even better, because npm makes it dead-simple for people to use your package. It's only an npm install away. And if your package does something useful, people will find it without you having to spread the word about it -- developers actively search npmjs.com for packages all the time to instantly add worlds of functionality to their apps.

Search

Due to the magnitude of npm, some critics even go so far as to claim that Node.js developers simply npm install whatever they need their app to do and never write a single line of code themselves, and that's actually not so far-fetched as it sounds, nor is it a bad thing. Why not build upon the experience of other developers that were faced with the same exact task at hand?

An Introduction to npm

Skip this if you're familiar with how npm works.

The npm CLI works by reading and writing to a file called package.json within your project's root which looks similar to this:

{
  "name": "my-cool-package",
  "version": "1.0.0",
  "description": "A cool package for demonstration purposes",
  "main": "index.js",
  "author": "Elad Nava <eladnava@gmail.com>",
  "license": "Apache-2.0",
  "dependencies": {
    "express": "^4.13.4",
    "mongoose": "^4.4.17"
  }
}

Install an npm package by running the following command within your project's root directory:

npm install express --save

npm will then fetch the popular Express package and extract it into the node_modules/ folder within your project's root directory.

The --save argument instructs npm to add the package and its installed version to your project's package.json.

When other people want to work on your project, they simply clone it to their workstation and run:

npm install

All of the dependencies listed within your package.json will then be automatically installed to their local machine.

A Package for Everything

The coolest thing about npm is that there's a package for almost everything. It is, by far, the largest package manager for any development language. Simply search npm for the functionality you're looking to add to your project, and there's a pretty good chance you'll find a package that does exactly what you need!

But sometimes, you'll be working on something so unique that you won't be able to find anything like it on npm. And since you love open source and want to give back to this amazing community, you'll want to publish your awesome package and give it a catchy name that will be easy to remember and to npm install. But how do you go about doing that?

Publishing Your First Package

It's actually easier than it sounds. Let's get to it!

Starting Out

Let's begin by naming your package. You'll want to pick a name that is both self-explanatory and easy to remember. Some of the most popular npm packages tend to go for English words:

  • express
  • request
  • async
  • forever
  • underscore

And the list goes on... But it's definitely not mandatory to pick an English word. Just make sure that the name corresponds to the functionality of your package, as that will help people find it with ease.

One thing to note here: npm doesn't scope your packages to your account like GitHub scopes your repositories. This means that you should double-check that someone didn't already publish a package with the desired name by plugging it into this URL:
https://www.npmjs.com/package/package-name-goes-here

Available Name

You gotta love npm for that 404 page. =) If you are presented with a different page, it probably means that the package name is already taken up by someone else.

Functionality

It's time to think about the core functionality of your package. For the sake of this example, let's build a simple package called is-null-or-empty, which will receive a string and return true if it's null, undefined, or empty, or false in all other cases. Feel free to substitute the package name and logic with your own idea.

This is how the package would be used:

var isNullOrEmpty = require('is-null-or-empty');

console.log(isNullOrEmpty("")); // true
console.log(isNullOrEmpty(null)); // true
console.log(isNullOrEmpty(undefined)); // true

console.log(isNullOrEmpty("Hello World")); // false

Pretty simple package, right? That's perfectly fine. Writing tiny packages that do just one thing is a practice known as Hyper Modular JavaScript, and it encourages the use of tiny packages that do one thing well to accomplish a more complex goal, as well as DRYing up our code.

The name I chose for the package is a little long, but you can definitely understand what it's supposed to do when it's named so verbosely. Sometimes our packages do something so specific that it would make sense to name them this way, so that people will find them easily and understand their purpose instantly.

Source Control

Alright, now that we've got both a name and an idea for your package, let's begin to write the actual code.

First things first -- we should set up source control. GitHub is recommended for this as npm integrates nicely with it, as we'll see later.

Create a new repository called is-null-or-empty under your GitHub account by visiting:
https://github.com/new

Next, open up a terminal and run the following to create a directory for your package:

mkdir is-null-or-empty  
cd is-null-or-empty  

Once inside, let's initialize a local git repository for your package, as well as hook up a remote origin to it (the GitHub repo you just created).

git init .  
git remote add origin https://github.com/{your-username}/is-null-or-empty.git  

Make sure to replace {your-username} with your GitHub username.

Package Metadata

Next, let's create a basic package.json file by running the following:

npm init  

npm will now ask us to input some details about the project. You can pretty much press Enter all the way through, but make sure to fill in the following fields:

  • Author: First Last <email@provider.com>
  • Description: Checks whether a given string is null or empty.
  • License : MIT / GPL-3.0 / Apache-2.0 (Check out http://choosealicense.com for help with this)

For the rest of the options, you can leave the default values as they are.

Notice how npm will automatically detect the GitHub repository you configured in the previous step. It will link to your repository in the npm package listing page for people to view the package source and help contribute to your package.

Finally, enter yes to write the package.json file to the disk.

npm init

Write the Code

Finally, the part you've been waiting for! Writing your package's oh-so-complicated logic.

We need to create a file called index.js as that is your package's configured entry point (specified using the main property in your package.json). When others require your package, this is the file that will be run first.

Open up your favorite JavaScript IDE (give VS Code a try!) and create a new file called index.js, pasting the following inside it:

// Main package function
function isNullOrEmpty(input) {
    // Returns true if the input is either undefined, null, or empty, false otherwise
    return (input === undefined || input === null || input === '');
}

// Make the main function available to other packages that require us
module.exports = isNullOrEmpty;

Notice that module.exports declaration. We must explicitly tell Node.js what methods we want to make accessible to others by using this declaration. Without it, no one will be able to access the isNullOrEmpty() function we defined inside.

Write an Example File

The best way to demonstrate how to use your package is to write an example script that makes use of it, documenting the return values of your package. Add the following example.js to your project with the following content:

// Change './index' to 'is-null-or-empty' if you use this code outside of this package
var isNullOrEmpty = require('./index');

console.log(isNullOrEmpty("")); // true
console.log(isNullOrEmpty(null)); // true
console.log(isNullOrEmpty(undefined)); // true

console.log(isNullOrEmpty("Hello World")); // false

Notice how the require statement calls for ./index instead of is-null-or-empty. In order to require your own package within your package's code, we have to directly reference its entry point, which is index.js, by writing require('./index'). Anyone else that installs your package will be able to require('is-null-or-empty') as expected.

Test It Out

Now it's time to make sure your package actually works! Run the example.js file with an IDE of your choice or simply by invoking node:

node example.js

As expected, here's the output:

Output

Documentation

This one's actually easier than you think. Simply create a README.md file within your project with the following Markdown-styled content for a basic Node.js package documentation:

# is-null-or-empty

A Node.js package that checks whether a given string is null or empty. A basic package for an npm publish tutorial.

## Usage

First, install the package using npm:

    npm install is-null-or-empty --save

Then, require the package and use it like so:

    var isNullOrEmpty = require('is-null-or-empty');

    console.log(isNullOrEmpty("")); // true
    console.log(isNullOrEmpty(null)); // true
    console.log(isNullOrEmpty(undefined)); // true

    console.log(isNullOrEmpty("Hello World")); // false

## License

Apache 2.0

The README.md is crucial -- almost no one will bother to sift through your package code to attempt to understand how to actually use it, especially if it's a large and complicated package.

Commit everything into your git repo and push it up to GitHub:

git add index.js package.json example.js README.md
git commit -m "Initial commit"
git push origin master

Publish the Package!

And now, the moment you've been waiting for -- publishing your package for the whole world to see!

If this is indeed your first package, you'll need to register on npm by running npm adduser. If you're already registered on npm, use npm login instead.

Here comes the big one:

npm publish

This one might take a few seconds, but once it's done -- so are you!

Congratulations! You just published your first npm package like a boss! Go ahead and run npm install is-null-or-empty and attempt to use your package in another project! =)