Mariusz Rajczakowski
Software Engineer
21 min read | 1 year ago

Create and publish your first npm package!


In this tutorial you will learn how to write and publish your first npm package. Source code is available on github and package is published on npm registry.


  • Create an account on github
  • Install node.js and npm (comes with node)
  • Install/update your npm to the latest version
    npm install npm@latest -g
      npm update -g
    (you can read more about npm here)
  • Create an account on npm registry
  • Create an account on circleci (sign up with github)
  • Create an account on codecov (sign up with github)

Getting started

1. Create your github repo

adding new repository

2. Choose name and description, then tick add readme checkbox, choose .gitignore for node and MIT license (most popular)


3. Then clone the repo on your local machine

  git clone

4. Set up the personalized init data for npm

  //set up your full name
  npm set “Mariusz Rajczakowski”
  //set up your email
  npm set “”
  //set up your website
  npm set “”

You can control what has being set up by opening ~/.npmrc. It should look like:

  vi ~/.npmrc

  // Rajczakowski

5. Then you are ready for your package initialization

  //cd into your cloned repo
  cd rademenes
  npm init

  //then choose package name (default is fine)
  //remember about the rules for name in package.json
  //(up to 214 characters, can't start with dot or an underscore,
  //no uppercase, only URL-safe characters)
  package name: (rademenes)
  //choose version 0.1.0 (feature according to semantic versioning)
  version: (1.0.0) 0.1.0
  //choose package description - be descriptive as this is how people
  //will discover your package when searching on
  description: minimalistic java script utility library
  //choose entry point to your program (in our case is src/index.js)
  entry point: (index.js) src/index.js
  //set test command
  test command: jest --coverage
  //set git repo (default is fine)
  git repository: (
  //choose keywords describing your package:
  keywords: javascript, utility library, functional programming
  //specify license (MIT will do)
  license: (ISC) MIT
  Is this ok? (yes)

After that you should see newly created package.json in root dir

  cat package.json

  //it should look like this
    "name": "rademenes",
    "version": "0.1.0",
    "description": "minimalistic java script utility library",
    "main": "src/index.js",
    "scripts": {
      "test": "yarn test --coverage"
    "repository": {
      "type": "git",
      "url": "git+"
    "keywords": [
    "author": "Mariusz Rajczakowski <> (",
    "license": "MIT",
    "bugs": {
      "url": ""
    "homepage": ""

6. Let's add engines property to package.json.

Npm treats engines.node as advisory and it will check node version when you install your package (not when you run it). We will use version equal or higher than 4.8.2.

     //rest of config
     "engines" : {
        "node": ">=4.8.2"

7. Create your first npm module

Bear in mind, it has to adhere to CommonJS module spec. We can start by creating an entry point to our app

  mkdir src
  touch src/index.js

8. Let’s then install jest testing framework

To read more about jest visit their docs

  npm install jest --save-dev
  //or with yarn
  yarn add jest --dev

  //after that create tests folder (jest naming convention)
  mkdir __tests__

9. Let’s also install codecov (coverage report uploader)

You can read more about codecov here

  npm install codecov --save-dev
  yarn add codecov --dev

Module's Requirements

What are we going to build

  • Our library will contains two functions which are useful for working with arrays and objects: pluck and pick
  • We will implement them in separate files then you can use them individually, additionally you will see how to work with exports from more than one files
  • We will try to follow tdd (test driven development) approach to implement them
  • When we finished, we will plug in circleci and codecov to automatically run tests and check test coverage whenever someone will make some changes to our repo
  • Then we will add badges which will be visible in our repo on github (one for build and one for test coverage)

Let's build our pluck function

  touch __tests__/pluck.test.js

  const pluck = require('../src/pluck'); //we can skip an extension if it's js
  //bear in mind we haven't created this file yet..

  //then we will write our first test
  test('it can pluck values for a given key from array of objects', function(){
    const data = [ { id: 1, name: 'Thomas' }, { id: 2, name: 'Lukas' }, { id: 3, name: 'Ann'} ];
    expect(pluck(data, 'name')).toEqual(['Thomas','Lukas','Ann']);

When you run your tests: (npm test or yarn test). You should see:


So first we create new module

  touch src/pluck.js

  // src/pluck.js
  'use strict';
  module.exports = function(arrayOfObjects, key){
      //normally we would go with map method on array prototype
      //but is not available prior to IE9 hence we will use loops:
      const newArray = [];
      const length = arrayOfObjects.length;
      for(let i = 0; i < length; i++){
      return newArray;

When your run your tests you should see:


This works, however what will happen if we have objects which don't have given property or they have it but down the prototype chain?

We don’t want to pluck those values, let's then write a test for that cases

  test('it can pluck values for a given key only when object has it as own property', function(){
    const person = { id: 3, name: 'William'};
    const ann = Object.create(person);
    //second object has no property name, third one inherits those properties from person
    //hence doesn’t have own ones
    const data = [ { id: 1, name: 'Thomas' }, { id: 2 },ann];
    expect(pluck(data, 'name')).toEqual(['Thomas']);

When we run our test suite we should see:


To fix that we will add an extra check:

  // src/pluck.js
  'use strict';
  module.exports = function(arrayOfObjects, key){
      //normally we would go with map method on array prototype
      //but is not available prior to IE9 hence we will use loops:
      const newArray = [];
      const length = arrayOfObjects.length;
      for(let i = 0; i < length; i++){
      return newArray;

After running the tests we should see:


Let's now build our pick function

  touch __tests__/pick.test.js

  //and add following lines:
  'use strict';
  const pick = require('../src/pick');
  test('it could pick a single property from an object', function(){
    const testObj = {a:1, b:2, c: 3};
    expect(pick(testObj, b)).toEqual(2);

When you run your tests you should see:


Let’s implement a basic functionality

  touch src/pick.js
  //then we will start with the following functionality
  'use strict';
  module.exports = function(obj, key){
    const newObj = {};
    newObj[key] = obj[key];
    return newObj;

When you run your test suite your should see:


However we will write more tests for edge cases when property does not exist or its inherited

  test('it could only pick a property which exist on object', function(){
    const parent = {z: 12};
    const testObj = Object.create(parent);
    expect(pick(testObj, 'z')).not.toHaveProperty('z');

When you run your tests now:


To fix that you will add an extra check in pick.js

  // src/pick.js
  'use strict';
  module.exports = function(obj, key){
    const newObj = {};
      newObj[key] = obj[key];
    return newObj;

Then when you run your tests:


Next step will be to change the API of pick function to accept array of keys as an second argument

We will start with test including the edge case with prototypical inheritance:

  test('it should pick many keys from an object if array given as an argument', function(){
    const parent = {z:3};
    const testObj = Object.create(parent);
    testObj['a'] = 12;

When you run your tests now:


We will now write an implementation

  'use strict';
  module.exports = function(obj, key){
    const newObj = {};

    if(typeof key === 'string' && obj.hasOwnProperty(key)){
      newObj[key] = obj[key];

    if(typeof key === 'object' && key.constructor === Array){
           newObj[prop] = obj[prop];
    return newObj;

Then when you run your tests:


Wrapping up a module

Let's finish up the module with multiple export in main entry point

  // src/index.js
  const pluck = require('./pluck');
  const pick = require('./pick');

  module.exports = {

Then we will modify our file

  # rademenes

  minimalistic java script utility library providing pluck and pick methods

  ## Installation
     yarn add rademenes
     npm install rademenes --save

  ## Usage
    //require at the top of your script
    const R = require('rademenes');

    const arrayOfObjects = [
      { id: 1, name: 'Thomas' },
      { id: 2, name: 'Mariusz' },
      { id: 3, name: 'John' }

    const onlyNames = R.pluck(arrayOfObjects, 'name');
    console.log(onlyNames);  // prints ['Thomas', 'Mariusz', 'John']

    const input = { firstname: 'John', lastname: 'Doe', age: 25, isAdmin: true };
    const fillable = [ 'firstname', 'lastname', 'age' ];
    const onlyFillable = R.pick(input, fillable);

    console.log(onlyFillable); //prints { firstname: 'John', lastname: 'Doe', age: 25 };

  ## Tests
    yarn test
    npm test

  ## Contributing
  When contributing to this repository, please first discuss the
  change you wish to make via issue, email, or any other method
  with the owners of this repository before making a change.

  ## Release History
  * 0.1.0 Initial release

Add, commit and push to github

  git add .
  git commit -m 'Initial release'
  git tag v0.1.0
  git push origin master --tags

Publishing on npm registry

Log in to npm registry with the same credentials you used on when you registered:

  npm login //then provide username, password and email

  //later when you checked that your package name is unique in searchbox
  //at you can run:
  npm publish

If everything goes well you should see:


Adding continuous integration for your repo

We will use the account on circleci (if you have not registered yet - signup with github)

Then go to projects tab in circleci and add new project (choose from the github account)

Follow the instructions there:


  //we will start by creating .circleci folder
  mkdir .circleci

  //then we will create a file there and edit it
  vi .circleci/config.yml

  //and we paste all below, then press esc, type :wq and press enter
  version: 2
      working_directory: ~/rademenes
        - image: circleci/node:4.8.2
        - checkout
        - run:
            name: update-npm
            command: 'sudo npm install -g npm@latest'
        - restore_cache:
            key: dependency-cache-{{ checksum 'package.json' }}
        - run:
            name: install-npm-wee
            command: npm install
        - save_cache:
            key: dependency-cache-{{ checksum 'package.json' }}
              - ./node_modules
        - run:
            name: test
            command: npm test

The commit those changes to github repo:

  git add .
  git commit -m 'added circleci config'
  git push

Then go to circleci and wait until build will finish. If everything go well you should see:


Adding coverage statistics to the repo

Start by adding following lines to package.json. That will tell jest to collect coverage metrics and store it in root dir in coverage folder.

     //rest of the config
    "jest": {
      "coverageDirectory": "./coverage/",
      "collectCoverage": true
  //also change this lines in package.json
  "scripts": {
    "test": "jest --coverage"
  "scripts": {
    "test": "jest --coverage && codecov"
  //it will allow to send statistics to codecov servers

Then go to your codecov account and add new repo from github account:


After you can commit changes you made to github repo:

  git add .
  git commit -m 'added coverage reporting'
  git push

Your build on circleci should be successful, moreover when you check your codecov account you will see test statistics.


Adding badges to the repo


Go to your repo settings, then click on settings icon, you should have an option 'status badges', click on it and copy the markdown.



Go to your codecov account, and in project settings click on settings and then badge, copy the markdown.


Modify your file and add those two badges like so:

  # rademenes


Commit those changes to github repo:

  git add .
  git commit -m 'added build and coverage badges'
  git tag v0.1.1
  git push origin master --tags

Then update your npm registry and publish:

  npm version patch -m 'Version %s - added build and coverage badges'
  //and then
  npm publish

When you check your npmjs account you will see v.0.1.1 there.

What next?

That's it! You made it! Congratulations! You created and published your first npm package. Now you are free to add more features, collaborate with other developers and share your code with others. Welcome to the open source world!

Source code is available here and your can also download a package from npm - more details here



Warning! This site uses cookies
By continuing to browse the site, you are agreeing to our use of cookies. Read our privacy policy