In this article, we are going to explore how to publish our open source (OS) code into the npm registry as a module.
npm is currently the largest software repository in the world with over 600 thousand modules published (As of January 2018). It’s used to publish from very small modules (1 line functions) to complete frameworks (like React) and even full P2P clients (like WebTorrent).
Introduction
Before we continue, this is the list of things we should have beforehand:
-
Node.js and npm installed (LTS recommended)
-
GitHub account
-
An IDE (I’ll be using WebStorm), a few options:
-
WebStorm (Free for OS & Education)
-
Terminal (I’ll be using iTerm with zsh in MacOS)
1. Creating an npmjs.com account
Our first step is to create an npm account. Now, there are two ways of doing that. The first is through the website and the second is through using npm’s CLI (which you should have installed already) with the command adduser
.
If you had already created your user or you just did through the website, you must now use npm login
in the terminal to store your credentials. adduser
command should have stored the credentials automatically (login
is just an alias)
To test what we just did, type npm whoami
to ensure that our credentials were stored.
2. Creating our project
Our first step is to create an new GitHub repository, for this tutorial I will be publishing a simple module which wraps async functions with debug
(a logger) logging for express
(a web framework). I’ll call it express-debug-async-wrap
for now. But is it available in the public scope? Just search it or go directly to the package.
If you searched for a simple word, there’s a chance a module that has it in its name or in its keywords and will show up, even then, your package name might be free to take. The safe your is to go directly with this url expression: https://www.npmjs.com/package/<package name here>
Great, we can proceed with the name express-debug-async-wrap
in mind. Note that we can use any name under our personal scope @username/my-package even if it’s already taken in the public scope.
Naming our modules is an important thing. Recently, npm updated it’s naming rules to prevent name hijacking. You can read more about it in this blog post. We can use A-Z, a-z, 0-9 and punctuations like dots, dashes, and underscores.
Creating the GitHub repository
With our name in mind, we continue to create the GitHub repository. On GitHub go to the top right corner and click the “+“ with an arrow by its side:
We add our project’s name and description. Select “Initialize this project with a README”. And finally, we add Node’s .gitignore and MIT License.
You are free to select the license that best suits you. Learn more here
Once we click on “Create repository”, we should have the following:
3. Adding our code
Cloning the GitHub Repository
To add our code we must first clone the GitHub repository in our machine. To do so, we must click on “Clone or download” green button in our repo and copy the url:
Next, we must clone the repository in our machine using git:
Initializing the npm package
Once we have the repository, we should “get into” it and initialize the directory with a package.json, to do so, we use npm init
and fill the blanks:
-
Version should start in 1.0.0 unless we are doing alpha/beta release
-
Default entry point index.js works for our this first case, but keep in mind if the entry point is different, maybe in
lib/
ordist/
-
Test command is completely up to you, I use and recommend
standard
code style for linting,ava
for tests fornyc
for code coverage. (These must be installed with as dev dependencies) -
Leave git as default, it should be the GitHub repo we just created.
-
Add as much relevant tags as needed
-
Match the license chosen in the repo
The package.json contents will be shown and the CLI tool will ask for confirmation:
Our directory should look like this in our IDE:
package.json is in red (Under WebStorm) because is untracked by git
Creating index.js
We now continue with the important part, the code, in a new file called index.js
:
We must use exports
or the real deal: module.exports
. We can export anything: a function, an object, an array, a class, a string, etc.
Note: To learn the difference between exports
and module.exports
we can read more here.
Committing our files to git
Last, but not least, we must add our files to our git repository. A quick git status
shows us the following:
We can see the recently created package.json
and index.js
. In my case, because I’m using WebStorm, I also see a .idea
folder, which is appended to the .gitignore
file to be ignored. Once we’ve ignored the unnecessary files, we add everything and commit:
4. Publishing our module
Although our npm modules don’t have to live in a public repository, I personally think they should, and they should match whatever is stored in the npm registry. So we tag this first version (new releases should be done with npm version
which automatically tags them), push to GitHub, push tags and finally publish to npm:
That’s it! Our module lives in the npm registry.
5. Completing our README
Our module can be used by anyone, but sadly, the page for it looks like this:
It’s empty and sad, no explanation on how to use it, nothing. We should definitely add a few things: basic badges, how to install, how to use, related packages and a footer stating our copyright and the license. For our module it looks like this:
# express-debug-async-wrap []() []() [](https://standardjs.com) [](LICENSE)
express async wrapper that passes custom debug instance and returns 400 as default error code
## Install
```
npm i -S express-debug-async-wrap
or
npm install --save express-debug-async-wrap
```
## Use
Require and initialize with `debug` instance:
```js
const debug = require('debug')('backend:routes:doc')
const wrapper = require(`express-debug-async-wrap`)(debug)
const express = require('express')
const router = express.Router()
router.get('/', wrapper(async (req, res) => {
await ...
await ...
res.send('OK')
}))
module.exports = router
```
## Related
- [express-route-autoloader](https://github.com/DiegoRBaquero/express-route-autoloader)
- [sequelize-express-findbyid](https://github.com/DiegoRBaquero/sequelize-express-findbyid)
## License
MIT Copyright © [Diego Rodríguez Baquero](https://diegorbaquero.com)
Once it’s done, we must create a patch version, push to GitHub and publish to npm. After committing our changes:
That’s it!
6. Final touches and homework
-
Important: Add tests and setup CI! (Travis recommended)
-
Add more badges: travis build, security related, etc. Here’s an example:
-
Share your module in social media, forums, IRC/Gitter channels
-
Tell me how you did and share me your module.
Leave a Reply
Your email address will not be published. Required fields are marked *