(npm) publish, and be damned!
10th May, 2019
9 min read
I recently published my first npm package and my colleague, Attila Vágó, suggested I write up some notes on the process. I'll point out that I am not an expert on this (I don't even play one on TV!) so you should take this with a pinch of salt.
I'm going to outline why you might want to publish an npm package, then show you how easy it is, and finally, an overview of the configuration options you need to know.
Motivation - why would you ever publish an npm package?
fun!
It's fun to learn!
forking an existing package
Maybe an existing package doesn't do what you need. Maybe it has been abandoned. Maybe you need to add some new configuration and port it to es6 at the same time. Whatever the reason, you want it? you can rebuild it. You have the technology.
code sharing
You might want to share some code between your own projects. Publishing it as an npm package makes that easier. If you need to restrict access to your published library you can also publish your package to a private registry so that only you and your team can install it - not all the options cost money.
Publishing your package in three easy steps
Let's jump right in!
It is actually really easy to publish an npm package. I'll show you how to do that first and then show you how to properly configure your package so you publish only the files you want, and provide a good description of how to install and use your package.
1. Login to your npm account from the terminal
You'll need to have an account, so if you don't have one, visit https://www.npmjs.com/signup and create one.
On the terminal logging in is straightforward
$ npm login
# prompts you for your email and password
You only need to login once after starting / restarting your terminal.
2. Increment the version of your package
Unless this is the first time you've published, you'll have to increment the version of the package or npm will reject it as it expects an updated version every time you publish.
{
"version": "1.0.0" // increment to 1.0.1
}
3. Publish!
The command below will publish your package
$ npm publish
# npm notice
# npm notice 📦 [email protected]
# npm notice === Tarball Contents ===
# npm notice 1.5kB package.json
# npm notice 1.1kB LICENSE
# npm notice 2.0kB README.md
# npm notice 1.5kB src/sort.js
# npm notice 865B src/fuzzy.js
# npm notice === Tarball Details ===
# npm notice name: my-colourful-sorter
# npm notice version: 1.0.1
# npm notice package size: 3.1 kB
# npm notice unpacked size: 6.9 kB
# npm notice shasum: d2ffe8d1c9f8f284319efca30e610edee091d993
# npm notice integrity: sha512-zbG1FeJIr3Ec1[...]EZaLTYm8TKaEg==
# npm notice total files: 5
# npm notice
# + [email protected]
Congratulations! I told you it would be easy.
Now for the slightly hard stuff - configuration.
Configuration - package.json
This is where the magic happens. The package.json
file contains all the details npm needs to properly package and publish your library to npm, and then install to the developer's project when they choose to use it.
Apart from your dependencies, the top three properties of the package.json file you really need for publishing are:
- files
- name
- version
There are further properties that are optional but usually required for anything more than a simple package:
- description
- keywords
- main / browser
Finally, there are some less important fields that are also useful - I won't be covering them here:
- engine
- homepage
- bugs
- licence
Configuration - three is the magic number
files
This is optional, but I consider it the most important field in package.json, which is why I am putting it first in this list. As it suggests, this property determines what files will be included in your npm package. You will see a lot of suggestions to use .npmignore
to blacklist whatever files you do not want included in the package - you probably shouldn't use it at all. Anyway, using the files
field is recommended by npm.
The files
field allows you to whitelist files by directly referencing them or using globbing patterns. These will override what is in your .gitignore
and .npmignore
file. As an example:
// package.json
{
"files": [
"src/**/*.js",
],
}
Will include all the js files in the root and sub-directories of the src
directory. The **
pattern matches any subdirectory paths.
The patterns are not just a whitelist, you can exclude files too, making the files
field very powerful. As an example, I like to have my unit tests in the same folder as my source files and these can be excluded using:
// package.json
{
"files": [
"src/**/*.js",
"!src/**/*.test.js"
],
}
Regardless of what you have in the files
field, these files are always included:
- package.json
- README
- CHANGES / CHANGELOG / HISTORY
- LICENSE / LICENCE
- NOTICE
- The file you specify in
main
field (see below)
name
This is the package name, and also what will be used to import
your package into a module, so best to keep it short and memorable. It also needs to be unique, but you should search on https://npmjs.com to check your package name has not already been taken.
You can have a shorter package name if you scope your package name with your own npm username. If you want to call your npm package colors
- a package that already exists - you can, if you use a scoped package name.
@paddingtonbear/colors
Installing this in a project would be just as simple.
$ npm install @paddingtonbear/colors
version
This is semver compliant. Keep it simple, start at 1.0.0
. Every time you publish your package to npm you will need to increment the version - you can use the handy npm version
command for this. If in doubt, increment the patch
number each time you publish.
$ npm version patch
This will increment your version 1.0.0
package to version 1.0.1
.
// package.json
{
"version": "1.0.1"
}
There are npm libraries that help you publish to npm - the excellent np, for instance - but I won't be covering them here.
Optional configuration
description
Your package's elevator pitch. Keep it short and to the point, this is what appears in the search results on npmjs.com.
The description should tell you exactly what problem the package solves.
This is a bad example.
A super-duper npm package I enjoyed writing and hope you will enjoy using it to sort colourful and other types of lists
Ah, now this is just what I need for my wallpaper database project!
Configurable list sorter that allows sorting by colour
keywords
Any keywords you provide will be used to improve search results. Try and include useful keywords - node and nodejs won't help, for instance. In our hypothetical example these might be a good choice
{
"keywords": [
"color",
"sort",
"rainbow",
"color-blind",
"protanomaly",
"deuteranomaly",
"tritanomaly"
]
}
main / browser
When your npm package is imported into a module the main
field defines what is returned.
For instance, if you define main
as follows
// package.json
{
"name": "my-colourful-sorter"
"main": "src/sort.js"
}
Where the src/sort.js
file in your npm package is
// src/sort.js
export default function doIt() { /* magic happens */ }
If you install your package in a project and import it into a module in that project, the import will be the doIt
method from the src/sort.js
file:
// wallpapers/index.js
import colourfulSorter from 'colourful-sorter';
:
colourfulSorter(someList); // this will execute the `doIt` function in your src/sort.js file
The browser
property is essentially the same as main
but intended for libraries that will be used in the UI.
README
Your readme
file is an essential part of your npm package. It's what helps a developer decide if your package is worth installing. At the very least it should describe what your package does, how to install it, and how to use it. Also, it's optional, but common to include badges highlighting the status of your CI pipeline.
description
You can't go wrong by including the name, and quoting the description from your package.json. Add a short paragraph expanding on the description and you're done.
Configurable list sorter that allows sorting by colour.
This sorter allows sorting colour names based on the hue
of the colour they represent. It can be configured to sort
in reverse order and can sort based on hues as affected
by colour-blindness - protanomaly, deuteranomaly, or tritanomaly.
installation and requirements
Developers need to know if a certain version of nodejs is required, and whether the package is best used as a production or development dependency.
Requires Node 8 or higher.
npm install --save @paddingtonbear/colors
How to use
You should give some working examples to highlight how to configure and use your npm package.
import colorsort from `@paddingtonbear/colors`;
const colorList = ['mango', 'chartreuse', 'vermillion', 'cyan', 'lavender'];
// ['vermillion', 'mango', 'chartreuse', 'cyan', 'lavender']
const result = colorsort(colorList, { order: colorsort.reverse });
API
The usage section should highlight some different ways of using your npm package, and even if you only have a small number of options you should still include an API section to explain them. An incomplete example is shown below.
colorsort(array, [options])
Returns an array of colours sorted in rainbow order.
options
Should be provided as an object literal. The properties and
values are listed below
order
Can be `colorsort.normal` or `colorsort.reverse`
etc.
Author
You should probably provide your name, non-private email, twitter, linkedin, blog, etc.
Author
Michelin Mann <[email protected]>
- [@tirechap](https://twitter.com/tirechap)
Licence
Finally, you should list the licence you applied to your repo - the MIT licence is a good choice if you are not sure what to use.
How?
Github allows you to add a licence to your repo when you create it. This will add a LICENCE
file to your repo that includes the standard MIT licence text.
Github has more information about choosing and applying a licence
README template
I've provided a template README.md file that you can download and use in your own projects.