5 Steps to publish my first npm package
Tags: npm, package, vue, tutorial
Published: 2020-04-26 19:40:07


{% twitter 1254491403511648257 %}

> I come to tell my experience and list what I have seen that is needed to publish a package like a boss.

### **Before we start**

If you are reading this post you should already know **nodejs** & **npm** and have them installed. If not, I recommend you to read its [about section](https://docs.npmjs.com/about-npm/) before continuing, it will help you understand what it is about. To start using it you just need to follow [its installation guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).

Now we're ready to continue!

---

### **STEP 1 - Create your package**

The first thing we need is to be clear about what name we're going to give our little package. We need to check that no one has used it before, look for it [in the search](https://www.npmjs.com/) and pray it's not taken yet.

Once you’ve decided the name, we are ready to create the package. You can choose between creating it directly by naming a folder as you chose and run **npm init** on it, or using the tools of your favorite framework.

In my case, I created a package in *Vue.js* using **Vue CLI**. Here's how I did it:

- First I install the CLI:

  ```html
  npm install -g @vue/cli
  ```

- Then I create the project and run it to see everything is working fine:

  ```html
  vue create chosen-name
  npm run serve
  ```

- Finally, I create the component and I register it globally

  To do it, I create a file **ChosenName.vue** in the *src/components* folder and started adding the code.

  In order to register it globally, I needed to create an **index.js** file in the same folder and add the following lines:

  ```javascript
  import Vue from "vue";
  import ChosenName from "./ChosenName.vue";

  const Components = {
      ChosenName
  };

  Object.keys(Components).forEach(name => {
    Vue.component(name, Components [name]);
  });

  export default Components;
  ```

  This way, the day we want to extend our package with a new component and make it a library, we will only need to import it into this file.

---

### **STEP 2 - Test it locally**

Like you, since it was my first time I had no idea how to test my package without publishing it.

Then I discovered **npm link**, thanks to [this post](https://medium.com/@the1mills/how-to-test-your-npm-module-without-publishing-it-every-5-minutes-1c4cb4b369be), where it explains how to use this wonderful command and gives you other options in case symlinks don't suit you. I recommend you to take a look and follow the option that best suits your case.

> Remember not to publish your package before you have tried it out in the local environment. Keep in mind that if you publish it, you aren’t convinced and you want to unpublish it, [you will not be able to publish it again](https://docs.npmjs.com/unpublishing-packages-from-the-registry#when-to-unpublish) under the same name.

---

### **STEP 3 - Upload it to GitHub**

We need to have our code visible to people who want to look at it, so we're going to host it on the most popular platform, GitHub.

> If you like BitBucket or another platform, you're free to choose the one you like best, but keep in mind that GitHub provides an issues url, which will be useful for reporting possible bugs they might find in your package.

Create your repository on GitHub and run the following commands, changing the repo url by yours.

```html
git init
git add .
git commit -m "My first npm package version"
git remote add origin https://github.com/<user>/<chosen-name>
git push origin master
```

Now we have what we need to complete the files I mention in the next step. Let's see it!

---

### **STEP 4 - Prepare package.json, README.md, License and a demo**

Now let's see how I had to prepare the **package.json** file so that *npm* could get all the data it is interested in. Most of the fields will already be filled in, having created our app with vue create, but let's check it.

Also, I'll tell you the most important thing when publishing your package, which is to have a good **README** and a **demo** ready, where people can be able to understand what your package is about and how to use it in their projects.

- **How to fill the package.json**

  Let's divide the file by parts to see in detail what we are interested in.

  First we will have to fill in the information about the package. We need to add the **name** we have chosen, the **version** (we will talk about this in *STEP 5*), a **brief description** of what our package does, the **keywords** by which people will be able to find our package in the npm search engine, and the **author**, adding our *name*, *email* and *website*, so that they can contact us.

  ```json
  {
    "name": "chosen-name",
    "version": "1.0.0",
    "description": "My first package on npm.",
    "keywords": [
      "first",
      "package",
      "npm"
    ],
    "author": "Your Name <youremail@domain.com> (<yourwebsite.com>)",
    ...
  }
  ```
  Once we have the basic information, we have to create a script to **create the bundle** of our package and specify to npm **which files we'll publish** and which of them will be the main one.

  In our case, once we run **npm run build-bundle**, it generates a *dist/* folder with several files, being ***.common.js** the one we will load as **main**.

  ```json
  {
    ...
    "main": "./dist/chosen-name.common.js",
    "scripts": {
      "build-bundle": "vue-cli-service build --target lib --name chosen-name ./src/components/index.js",
    },
    "files": [
      "dist/*",
      "src/*",
      "public/*",
      "*.json",
      "*.js"
    ],
    ...
  }
  ```
  Since we've already created a **repository** we can now use it so people can report bugs, or simply view our code on GitHub. Just add the **urls** below to your package.json and change them by your repo.

  Also, as we want to have a public package we need to set **private** to *false* and add the type of **License** we choose.

  ```json
  {
    ...
    "homepage": "https://github.com/<user>/<chosen-name>",
    "bugs": {
      "url": "https://github.com/<user>/<chosen-name>/issues",
      "email": "<youremail@domain.com>"
    },
    "repository": {
      "type": "git",
      "url": "git+https://github.com/<user>/<chosen-name>.git"
    },
    "license": "MIT",
    "private": false
  }
  ```

- **README & LICENSE**

  Although it is a very important part of our package, fortunately both files are very easy to create.

  To generate our own license, GitHub itself has an option to generate the LICENSE file with the type we choose, in my case I have chosen to use the MIT license, [here](https://github.com/Dawntraoz/vue-tweet-feedback/blob/master/LICENSE) you can see the generated file.

  In the case of the README you can be guided by [the one I created for my package](https://github.com/Dawntraoz/vue-tweet-feedback/blob/master/README.md), where the important parts are:

  - **Title, description and demo**

    Simply add the **name** and basic **description** of your package, as in the case of *package.json* and provide a link to the **demo** we have created, if applicable.

  - **Installation and use**

    Here you can add the **commands** that must be run to get your package and a **use case** or several, depending on what type of project it will be used on.

    > In my case it was necessary to explain how to use it in Nuxt as well.

  - **Options and slots**

    Here it's interesting to create **tables** that exemplify what type of data can be entered in our component, as the **properties/options** are called and what default value they usually have. This is a very simple way to expose the possibilities they have when using your package.

  - **Author and license**

    Mention the license used and the creators of the package.

  > I added a **Set up** section too, in case someone wanted to set up my project in their local environment.

- **How I made my demo**

  If your package has many use cases, you may want to create a website as a demo. In it, you can show the code needed to generate each use case.
A clear example of this type of demos is [Slick, by Ken Wheeler](https://kenwheeler.github.io/slick/), a great job that saves you hours in your developments!

  But, if, as in my case, your package has a unique or lesser functionality, I recommend you to create a project in [Codepen](https://codepen.io/) or [CodeSandbox](https://codesandbox.io/s/), you will be able to see how to implement it and the result at a glance. They make our lives easier!

  Here is my example if you want to check it:

{% codesandbox cw16g %}

---

### **STEP 5 - Publish your package**

We are now ready to publish our first package 😍

Generate your bundles with:

```html
npm run build-bundle
```

Then, create an account or log in on [npmjs](https://www.npmjs.com/signup). If you prefer to run commands instead, type:

```html
npm adduser /* Sign up */
npm login /* Log in */
```

Verify your npm user credentials:

```html
npm whoami
```

For our package we will need a version control, as we see on package.json, what better than using the one [recommended by npm](https://docs.npmjs.com/about-semantic-versioning). We just need to use the npm version command each time we need to update our package, using the following options:

- First release
  
  When we uploaded the first version, package.json need to have the field version as a 1.0.0.

- Bug fixes (**Patch** release)
  
  Increment the third digit: 1.0.1, 1.0.2, …
  
  ```html
  npm version patch
  ```

- New features (**Minor** release)

  Increment the middle digit and reset last digit to zero: 1.1.0, 1.2.0, …

  ```html
  npm version minor
  ```

- Changes that break backward compatibility (**Major** release)

  Increment the first digit and reset middle and last digits to zero: 2.0.0 (v2)
  
  ```html
  npm version major
  ```

And finally, we're ready to run the **magic command**:

```html
npm publish --access public
```

Voilà! Our package is already part of npm and now with the command **npm install chosen-name** we can add our package to all our projects 😍