How to publish a npm package in four steps

Vinicius Marchesin Araujo
7 min readJan 23, 2019

--

Woman using laptop computer besides person wearing hat. Unsplash

You’re a junior developer that recently landed on the JavaScript ecosystem. There’s so much going on that you have no idea where to start. Maybe try React? That library is cool, I should try it. Why isn’t this working?

One thing that I found is that being part of the ecosystem is the quickest way to understand it. That’s why in this article you’ll learn how to publish a npm package and get it working in your projects as fast as possible.

We’ll be using babel and webpack 4 to ship compact and idiomatic JavaScript code.

You can clone the repo that contains all the code from this article and follow along, or start from scratch.

git clone git@github.com:vmarchesin/how-to-publish-a-npm-package.git

The code is split into four branches, and I’ll explain where we are at each point. If you get lost, just jump into the next branch and you’ll catch up. The master branch has the finished package ready to be shipped.

Step One

First, we need to install our dependencies. We’ll be using babel and webpack, which I recommend for every project. You’ll see that our library is so simple that this wouldn’t be necessary, but we’re doing it for learning purposes.

It’s good to setup a Github repository for your npm package beforehand, if you’re not using my sample. You can find out how to create one here.

Run npm init inside your git directory and follow the prompts. If you don’t know what to put in a field, just leave it blank.

Install all of the dependencies by running:

npm i -D @babel/core babel-loader webpack webpack-cli

npm i is a shorthand for npm install and -D is a shorthand for --save-dev which means you’ll be saving these as Dev Dependencies (they won’t be shipped with your code).

Also let’s create a .gitignore file so you don’t accidentally commit the node_modules folder. Just add node_modules inside the .gitignore file and you’re good to go.

A good practice is to add a README.md file so people know what your library is about. Create one.

If you want to jump to this point, just checkout the step/one branch. If you do this instead of installing the packages yourself don’t forget to run npm i to install everything.

Step Two

Now it’s time to write our library. Let’s implement a random number generator. Let’s call it choice in honor of Python, even though it has nothing to do with the actual Python method.

Our file structure should look like this:

|-src/
| | bool.js
| | float.js
| | index.js
| | integer.js
| .gitignore
| LICENSE
| README.md
| package-lock.json
| package.json

If you don’t have the LICENSE file, don’t worry. You can copy mine and just change the copyright to your name. The MIT license is a very permissive license, and enables people to freely copy and/or modify your code as long as they credit the original source. You can use any license you desire.

The code for each file inside the src/ should look like this.

Put these inside the src folder

We export the choice method, that expects a max , min and options arguments. If we pass { float: true } as the options object we get a random float, if we pass { bool: true } we get a boolean, and if we don’t pass anything we get an integer.

We’re able to use the import and export syntax because we’re using babel. We haven’t configured it yet, but we will on the next step.

If you want to jump to this point, just checkout the step/two branch.

Step Three

Now it’s time to create our bundle. At this point you could just ship the src folder and it would work, most of the time (ours wouldn’t because we’re using import and export , but you could just change to require and module.exports to make it work). We can do better.

Webpack is a module bundler, meaning it does a better job than you in shipping code efficiently. It’ll minify and, alongisde babel-loader, transpile your code to be exported as a CommonJS module. CommonJS defines a module format and makes it readable by most JavaScript environments.

We’ll put our webpack config in a file called webpack.config.js .

Put this in your root folder

We just defined our webpack configuration. mode: 'production' enables various performance improvements in our final bundle. entry defines the main file in our module, which is the default export. output defines where our module will be exported, in this case it will be the file dist/index.js . The rules section inside module tells webpack to use babel-loader on all .js files, and the resolve section is there so we don’t need to add the file extension on our import statements.

Now that we configured webpack we need to tell our package.json how to build our module. Make sure you have this inside your package.json :

...
"main": "dist/index.js",
"scripts": {
"build": "webpack --mode production"
},
...

Our main file is the one that will be called when we declare our module as a dependency. As you can see it’s the file generated by webpack. Also define the build script.

Now just run:

npm run build

You’ll see the dist folder created. You don’t want to publish this folder to your Github repo, so add a new line inside your .gitignore telling you don’t want dist to be staged.

If you want to jump to this point, just checkout the step/three branch.

Step Four

We’re almost ready to publish our package! Now, before we publish we need to make sure it’s working. We can use npm link to test it. npm link Creates a virtual link to a module, simulating a npm install.

Follow these steps:

  1. Inside your module directory run npm link to create a virtual link to this module.
  2. Find yourself a project you’re working on, and run npm link <your_module> inside its folder. Take a note here, your module name isn’t the directory name your module is in. It’s the name declared inside your package.json file.
  3. Import/Require your module inside your project and test it. It’ll be treated as if it was installed as a dependency.

If something isn’t right all you need to do is update your module and run npm run build again. It’ll automatically update your virtual link and reflect the changes in your project so you can test it.

By the time you are done just run npm unlink inside the module directory and npm unlink <your_module> inside your project directory.

If everything is working, it’s time to publish. The short version is:

  1. Create a .npmignore file
  2. Create an account on npmjs.com (if you dont’t have one)
  3. Run npm login
  4. Run npm publish inside your module directory

Let’s break it down.

Create a .npmignore file in your root folder. It acts the same way as .gitignore does, but tells npm what you want to discard from the final module. Put src and webpack.config.js inside .npmignore , as we don’t want our source code and the webpack config to be bundled with our module.

Create an account on npmjs.com if you don’t have one already. You’ll need it to publish your module under your account. After the account is ready, run npm login in your machine and fill in the credentials.

Now, inside your module directory run npm publish . It will retrieve the version defined inside your package.json and publish it to npm using the same version. You can’t publish again using the same version, or a previous one. You can read more about versioning here.

Don’t forget to build before publishing. If you don’t you will end up publishing an empty module.

Article update: You can avoid this problem by adding a prepublish script to your package.json. This will ensure that the build will always run before you publish your package in case you forget to manually build it. Just add the script to your package.json.

...
"scripts": {
...
"prepublish": "npm run build"
},
...

One more thing: if you try to publish your package using the same name as the one from this article, how-to-publish-a-npm-package , it won’t work. Make sure the name of the package inside your package.json is different.

If you want to jump to this point, just checkout the step/four branch.

Resultado de imagem para npm loves you
And so should you

You’re done!

Now you can install your module inside any project! Find one and try it out:

npm i -S <your_package_name>

You can try this package too:

npm i -S how-to-publish-a-npm-package

You can check the package at npmjs.com as well:

Now go out there and publish. The open source community awaits you.

You can find me on my website. Thanks for reading this article.

--

--

Vinicius Marchesin Araujo

Front-end developer and dolphin impersonator. Currently working as a JavaScript Developer at @Socialbakers in Prague. | https://vmarches.in