Boldizsár's programming blog

Create your own npm package

May 12, 2019 | 6 Minute Read

Have you ever wanted to create your own npm package? I'm gonna show you how easy it is.

Recently I came across a situation where I wanted to test if a timezone is a valid timezone so I first looked at npm packages if there was one that could solve my problem. I ended up using moment-timezone because I couldn’t find a package that’s single aim was to check if a timezone exists or not. I could check it with moment-timezone but it contains so many other things so if you just want to have that functionality then why would you want to install much more? Then I thought I should create a simple package that’s single purpose is to check if a timezone is valid or not. I was also curious about how to create an npm package as I hadn’t done it before. It turned out to be pretty easy and I’m gonna share it with you now.

First you need to have an npm account. If you don’t have then go to npm website and register. By the way if you don’t know what npm (Node Package Manager) is it is the default package manager for NodeJS. It is a place which stores many many libraries that you can download so that you don’t reinvent the wheel. It also offers private repositories and with them for example companies can have their own packages for internal use under their own namespace.

Once you have registered an npm account login in your terminal.

npm login

The main steps

Now it’s time to start setting up the npm module. We have to basically do 3 things. Let’s see them. 👨‍💻

  1. Create the package.json file for your module.
  2. Create your module’s logic and then create a file that you’ll export. So this is the file that will be required by its user.
  3. It would nice to write some tests too so don’t forget about them. 😛

1. Creating the package.json file

npm init

There are some required fields. These include name, version, main. You must specify these field. I also suggest adding keywords too as npm allows searching for tags so people might find your package this way.

2. Write the logic and create an export file

I’m creating a module to check if a timezone is valid so I downloaded a list of timezones from here and created a timezones.json file for them. Then I created a file index.js which will be the file I’m gonna export. After that I wrote the logic for this module.

const timezones = require('./timezones');

const timezoneMap = new Map(timezones.map(t => [t, true]));

module.exports = timezone => {
  if (!timezone) throw new Error('I need a timezone');
  if (typeof timezone !== 'string')  throw new Error('The timezone must be a string');
  return timezoneMap.has(timezone);
};

I created a HashSet like structure in order to get the result in O(1) instead of traversing through the list every time. I’m exporting a single function which should receive a timezone. I’m doing some basic checks on that value as this function should receive a single string.

3. Let’s test 👻

I’m gonna install Jest which is a test framework so I can write some tests.

npm install --save-dev jest

And here are some basic tests. Some of you might argue that this should have been done before. I agree that TDD requires that but in this article I wasn’t following those principals.

const timezoneValidator = require('./index');

describe('GIVEN a TimezoneValidator', () => {
  describe('WHEN it is passed nothing', () => {
    test('THEN it should throw an error', () => {
      expect(() => timezoneValidator()).toThrow()
    });
  });

  describe('WHEN it is passed a not string argument', () => {
    test('THEN it should throw an error', () => {
      expect(() => timezoneValidator(12)).toThrow()
    });
  });

  describe('WHEN it is passed a valid timezone', () => {
    test('THEN it should return true', () => {
      expect(timezoneValidator('Europe/London')).toBe(true)
    });
  });

  describe('WHEN it is passed a string that is not a timezone', () => {
    test('THEN it should return false', () => {
      expect(timezoneValidator('Foo/Bar')).toBe(false)
    });
  });
});

After having seen all of our test passing it’s now time to publish our new shiny package. If you have a free npm account as I do you can publish public packages for free. Should you wish to publish private packages then you have to pay.

npm publish

Our package is live. It takes some time for npm to index it but on your profile page you should already see it. Let’s test it again. Create a new folder and npm project.

npm init -y
npm i timezone-validator

Create an index.js file and we can try the new package.

const timezoneValidator = require('timezone-validator');

console.log(timezoneValidator('America/Denver'));
console.log(timezoneValidator('Foo/Bar'));
console.log(timezoneValidator(new Array()));

On npm you can also find this package and it is ready to be used by the public.

Wrap up

This has been it. In this article I showed you how easy it was to create your own npm package that can be used by other devs too. Even with the free product of npm you can publish unlimited public packages which is very nice. Until my next article, Bye.