DEV Community

Cover image for Creating your first npm package
Dan Vega
Dan Vega

Posted on • Edited on • Originally published at danvega.me

npm Create Package JSon Creating your first npm package

This weekend I started working on my first ever npm package. I can't believe for how long I have been writing code that I never bothered to create my own npm package but here we are. I built my newest site using Gridsome and markdown and you can read all about that here. In the markdown files, I wanted an easy way to insert a twitter status and embed the tweet.

I will tell you more about that Gridsome plugin in a future blog post but for now, I want to show you how you can create your very first npm package. I learned a few things while working on this and I would like to share them with you.

Prerequisites

I am going to assume you at least know what node & npm is and have written JavaScript before. If you don't know either of these and want me to write something up on getting started with those please let me know.

There are a few things that you're going to need before we dive in and start writing some code.

Creating your npm package

The first thing you are going to do is create a new folder to hold your npm package. For this example, I am going to create a new directory called wrap-with-poo. Yes, you read that correctly.

Go into that folder and type the following:

npm init
Enter fullscreen mode Exit fullscreen mode

This will ask you a bunch of questions and then create a package.json. If you don't know answers to certain questions just yet don't worry, you can come back and answer them later.

This utility will walk you through creating a package.json file.
It only covers the most common items and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterward to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (wrap-with-poop)
version: (0.1.0) 0.1.0
description: This package will take any string you give it and wrap it with the poop emjoi
entry point: (index.js)
test command:
git repository:
keywords: node,npm
author: Dan Vega
license: (ISC) MIT
About to write to /Users/vega/dev/npm/wrap-with-poop/package.json:

{
  "name": "wrap-with-poop",
  "version": "0.1.0",
  "description": "This package will take any string you give it and wrap it with the poop emjoi",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "node",
    "npm"
  ],
  "author": "Dan Vega",
  "license": "MIT"
}


Is this OK? (yes) yes
Enter fullscreen mode Exit fullscreen mode

Writing your plugin

Next open this project up in Visual Studio Code and create index.js. The reason you're creating this file is that in your package.json you said that this was your entry point. In your index.js add the following code:

module.exports = (str) => {
    return `💩${str}💩`;
}
Enter fullscreen mode Exit fullscreen mode

The module.exports object allows us to organize some related code and then expose it as a module. This means that when we are done we could import this module into another application. In this case, we are assigning an arrow function which means we are exposing a single function that takes an argument called str and returns that string wrapped with the poo emoji. That is all you need to do with this project. It is a pretty simple package but it will help walk through a few things.

npm local development

Now that you have our package ready to go you need to test it in another project. In the real world, you should be writing some unit tests against it but I want to save that for another article & screencast.

Next, create a new directory (outside of your package) called wrap-with-poo-testing. You will again need to run npm init but this time you can add the -y argument to skip all of the questions, they are less important this time.

npm init -y

Wrote to /Users/vega/dev/npm/wrap-with-poo/package.json:

{
  "name": "wrap-with-poop",
  "version": "0.1.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
Enter fullscreen mode Exit fullscreen mode

NPM Install

In this project create a new file called app.js. This is where you are going to use your new wrap-with-poo package. This is normally where you would normally install the npm package you needed by running the following command.

npm install wrap-with-poo
Enter fullscreen mode Exit fullscreen mode

The problem with this is that you haven't published your new plugin yet so it isn't in npm. You need a way to reference the package locally while you're developing it. You could run npm install with the absolute path to the package.

npm install /Users/vega/dev/npm/wrap-with-poo
Enter fullscreen mode Exit fullscreen mode

Which would update your package.json to look like this

{
  "name": "npm",
  "version": "0.1.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wrap-with-poo": "file:../wrap-with-poo"
  }
}
Enter fullscreen mode Exit fullscreen mode

If you need to test out pre-install/post-install hooks in your package then you will want to use this approach. If you don't care about the best way to develop NPM projects locally is by using npm link.

NPM Link

npm link is a process that allows you to create a symbolic link between your project and the dependency. First, you need to move into the directory wrap-with-poo and run the following command.

npm link
Enter fullscreen mode Exit fullscreen mode

This will take your package and create a symbolic link in the npm global folder to it.

/Users/vega/.nvm/versions/node/v10.15.0/lib/node_modules/wrap-with-poo -> /Users/vega/dev/npm/wrap-with-poo

This means that your project can be used in any project with one more simple step. The next thing you need to do is to move into the project wrap-with-poo-testing and run the following command.

npm link wrap-with-poo
Enter fullscreen mode Exit fullscreen mode

This will output the following: /Users/vega/dev/npm/wrap-with-poo-testing/node_modules/wrap-with-poo -> /Users/vega/.nvm/versions/node/v10.15.0/lib/node_modules/wra
p-with-poo -> /Users/vega/dev/npm/wrap-with-poo

That is all there is to it, no need to install the dependency. You are ready to begin writing some code to play with you new plugin. Open up the app.js and add the following code.

const poo = require('wrap-with-poo');
const boring = 'This is a boring string';
const fun = poo(boring);

console.log(fun);
Enter fullscreen mode Exit fullscreen mode

And run the following command from the integrated terminal

node app.js
Enter fullscreen mode Exit fullscreen mode

And you will get the following output

💩This is a boring string💩
Enter fullscreen mode Exit fullscreen mode

Publish Source Code

Now that we know our project works its time to make it public for everyone to use. If you haven't done so yet I would add your project to Github or whatever source code hosting you prefer.

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/cfaddict/wrap-with-poo.git
git push -u origin master
Enter fullscreen mode Exit fullscreen mode

Now that it is on Github go back and add an entry to your package.json so everyone knows where to find the source code using the homepage key.

{
  "name": "wrap-with-poo",
  "version": "0.1.0",
  "description": "This package will wrap any string you give it with the poop emoji",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "node",
    "npm",
    "poop"
  ],
  "author": "Dan Vega",
  "license": "MIT",
  "homepage": "https://github.com/cfaddict/wrap-with-poo"
}
Enter fullscreen mode Exit fullscreen mode

Publishing NPM Package

It is now time to publish our project to npm so that anyone can use it. If this is your first time publishing a package open up a terminal in the wrap-with-poo directory and type the following command.

npm adduser
Enter fullscreen mode Exit fullscreen mode

This will ask you for your npm account information such as username, password, and email.

vega wrap-with-poo (master) $ npm adduser
Username: therealdanvega
Password:
Email: (this IS public) danvega@gmail.com
Logged in as therealdanvega on https://registry.npmjs.org/.
Enter fullscreen mode Exit fullscreen mode

Now you're ready to publish but there are a couple of things you need to remember. First every npm package must have a unique name. I would head over to npm and do a quick search for your package. I have already published the package wrap-with-poo so yours will need a new unique name.

The next thing you need to know is that your version number matters. I start with 0.0.1 and work my way up from there. Once you publish a specific version you can't publish the same version again. It is a good idea to build a number of features into a version and then publish that. If you run

npm version
Enter fullscreen mode Exit fullscreen mode

It will tell you what your current version is.

{ 'wrap-with-poo': '0.1.0',
  npm: '6.7.0',
  ares: '1.15.0',
  cldr: '33.1',
  http_parser: '2.8.0',
  icu: '62.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.34.0',
  node: '10.15.0',
  openssl: '1.1.0j',
  tz: '2018e',
  unicode: '11.0',
  uv: '1.23.2',
  v8: '6.8.275.32-node.45',
  zlib: '1.2.11' }
Enter fullscreen mode Exit fullscreen mode

If everything looks good you can publish your new project by running

npm publish
Enter fullscreen mode Exit fullscreen mode

This might take a few seconds but if everything went ok your package should now be live on npm.

Congrats on publishing your first npm package!!!

Now you can go into any project that already has a package.json and type the following

npm install wrap-with-poo
Enter fullscreen mode Exit fullscreen mode

And use it just like we did in our testing example above.

Documentation

I know some people say that you should create documentation from the beginning but I am not always sure what my code is going to end up looking like so I usually wait on this. Create a README.md in the root of your project and add some information about your project.

  • What does your npm package do?
  • Why did you create it.
  • How do you install it?
  • Are there any configuration options?

Conclusion

As I said at the beginning of this article I can't believe I published my first npm package this weekend. I just never really had a need to do so until now but I was really excited to learn how easy it was. If this is your first npm package please leave me some comments or tweet at me when yours is live!

Happy Coding!
Dan

This article was first posted on my blog at https://www.danvega.dev/blog. If you found this article interesting please consider subscribing to my newsletter or following me on Twitter.

Top comments (33)

Collapse
 
dance2die profile image
Sung M. Kim

This is an article I wish I had read before struggling so long to publish an NPM package 👍

Collapse
 
therealdanvega profile image
Dan Vega

Aww thank you for the kind words :)

Collapse
 
jvarness profile image
Jake Varness

Totes gonna use wrap-with-poo in my next package.

Collapse
 
juanfrank77 profile image
Juan F Gonzalez

As always you bringing in the real value Dan, thanks a lot for this! Been wanting to do this for quite some time but it seemed so daunting

Collapse
 
therealdanvega profile image
Dan Vega

You are too kind Juan. Thank you, my friend :) It does seem pretty overwhelming until you realize it isn't :)

Collapse
 
gifco profile image
GifCo

Ok this is great and all but it's 2019 and your example would be most suitable for front end use so why would you NOT even mention that thia should be published as an ESM not common.js. or ideally both.

Collapse
 
therealdanvega profile image
Dan Vega

Great questions. I just thought this was a good starting point. It's hard to talk about something new and not include everything the reader might need. I thought I would keep this simple and stick to the basics but I do appreciate your feedback. Thank you, Giff.

Collapse
 
joshichinmay profile image
Chinmay Joshi

Timing of your blog couldn't be better. I'm struggling with some problems, and going to refer this to solve the issues.

Thanks!!!

Collapse
 
therealdanvega profile image
Dan Vega

Great to hear. Let me know if you run into any issues, I am always looking for something to write about.

Collapse
 
_mertsimsek profile image
Mert Simsek • Edited

Thank you for article, that's a spirit :)

Collapse
 
feralamillo profile image
Feralamillo

Great tutorial!! I followed and have my first npm package live: npmjs.com/package/check-osaurus

thank you very much for the tips. I wonder if there is a better way to connect directly from github instead of having to do it manually.

Collapse
 
apol0x profile image
Apol0x

Thank you so much for the post,I thought a lot of times inform myself about this, and you explain it very clear

Collapse
 
therealdanvega profile image
Dan Vega

Thank you :)

Collapse
 
craigiswayne profile image
Craig Wayne

Thank you Dan!

Been meaning to actually start packaging our angular components into independent npm packages.

Didn't know where to start! So thank you so much for this 🥳

Collapse
 
antonreshetov profile image
Anton Reshetov

It is very strange to start with version 0.0.1, that is, with fix bug

Collapse
 
therealdanvega profile image
Dan Vega

Why is it strange? I am saying that this is the very first release of my plugin. It has some work to do before I consider it a stable 1.0 release.

Collapse
 
antonreshetov profile image
Anton Reshetov

Because it is incorrect to start versioning from the version which is intended for a fix of any bug
semver.org/#how-should-i-deal-with...

Thread Thread
 
therealdanvega profile image
Dan Vega

Oh, I thought it was at 0.1.0. Yes, I would agree with that. Will update, thank you!