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.
- Visual Studio Code or your favorite editor
- Node & NPM
- NPM Account
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
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
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}💩`;
}
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"
}
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
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
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"
}
}
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
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
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);
And run the following command from the integrated terminal
node app.js
And you will get the following output
💩This is a boring string💩
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
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"
}
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
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/.
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
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' }
If everything looks good you can publish your new project by running
npm publish
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
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)
This is an article I wish I had read before struggling so long to publish an NPM package 👍
Aww thank you for the kind words :)
Totes gonna use
wrap-with-poo
in my next package.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
You are too kind Juan. Thank you, my friend :) It does seem pretty overwhelming until you realize it isn't :)
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.
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.
Timing of your blog couldn't be better. I'm struggling with some problems, and going to refer this to solve the issues.
Thanks!!!
Great to hear. Let me know if you run into any issues, I am always looking for something to write about.
Thank you for article, that's a spirit :)
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.
Thank you so much for the post,I thought a lot of times inform myself about this, and you explain it very clear
Thank you :)
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 🥳
It is very strange to start with version 0.0.1, that is, with fix bug
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.
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...
Oh, I thought it was at 0.1.0. Yes, I would agree with that. Will update, thank you!