Simple guide to creating and publishing npm modules.

When I was first looking into publishing npm modules I was a bit overwhelmed with where to start, and I had a few misconceptions. I always thought that “I had to write ES5 code” and that “everyone is watching you and laughing at your mistakes”. Turns out it’s really simple, and surprisingly quick to do! This post will be covering creating a React component, but if you want to create a plain old JavaScript module you can follow the exact same exact steps. We will be using Rollup for writing ES6 code, but letting us distribute ES5 code.

The 8 steps to publishing a npm module are:

  1. Creating a distributable module using Rollup
  2. Publishing it to npm
  3. Oh.. I guess that’s it.

Creating a distributable module

Set up

Rollup have created a small starter project that I forked and added support for React and JSX, and can be found on Github (rollup-starter-project-react). We will clone this, delete any references to the git repo it was cloned to, and add our own git repo.

  1. Clone the starter project
    git clone https://github.com/karl-run/rollup-starter-project-react.git
    
  2. Delete references to git, and add our own (create the repo on your git service of choice).
    rm -r .git
    git init
    git remote add origin git@example.com:karl-run/our-awesome-component.git
    git add .
    git commit -m "Initial commit"
    git push --set-upstream origin master
    
    All these steps are simply “cut all ties to original repo” and then “point this ‘fresh’ repo towards our own git”.
  3. Install all dependencies by running yarn if you use yarn or npm i if you use npm. (From here on out I’ll only list yarn-commands.)
  4. Make it ours! Change the current files with modules name: package.json lines 2, 5, 19, 32 and 38 with the typical kebab-case-name. Is rollup-config.js change line 27 with a camelCaseName.
  5. Check that everything installed by running yarn build

Deveplopment

Structure

Open up the project in your favorite editor, and let’s look into the folder structure a bit. The files of importance, and in structure found in the starter project:

1.  lib/
      index.js
      index.css
      utils.js
2.  test/
      index.test.js
3.  dist/ (generated)
4.  package.json
5.  rollup.config.js
6.  .babelrc
7.  .eslintrc
  1. lib/

    The lib folder. This is your source folder, you put your code here. The entry point, or in our case, the main exports of our application will go in the index.js. If we only have a single component or function that we need to export we can use export default ExampleComponent, or we can use export { Several, Components }.

    We can have as many or as few files in the lib/ folder. The most important thing is that the index.js file is the entry point to the application.

  2. test/

    This is all our tests go! The starter project is configured to use jest and enzyme for quick and easy testing of React components. For a simple intro to testing React components, check out my first blog post, “Unit testing React components, 5 basic techniques”.

  3. dist/

    This is the folder where the files generated by Rollup will end up. This will be the actual code that will be executed when people use our module. The entry point ("main") in package.json will point to the file here that Rollup creates.

  4. package.json

    Same old package.json as ever, have a quick look at scripts and make your self familiar with the commands.

  5. rollup.config.js

    The config file for the bundler we are using, Rollup. It’s not big, and it’s not advanced. The plugin section has two entries, postcss to let us inline our CSS style (only required if you use CSS in your component), and babel, to let us write modern and sleek ES6, while our output code is good old and well supported ES5.

    The main configuration section has a entry-point, which is our lib/index.js file, our plugins, externals, globals. globals is where we need to define any external library that we use. This is because rollup doesn’t bundle your dependencies’ code, meaning that whoever use your module will have them installed on their system, and when they bundle their code your module will use that library. globals is defined as id: name pairs, meaning that react which is imported like this import React from 'react' will be defined here as react: 'React'.

    The targets array is if you want to produce more than one kind of module. For simplicity we will create a single UMD. If you want to get down and dirty with creating several modules (for example letting your users use much more terse and efficient ES6 code if they want), have a look at Rollup’s documentation.

  6. .babelrc

    If you want to use even more modern JavaScript, this is where you add them.

  7. .eslintrc

    The starter project is set up to use eslint with the airbnb lint preset. This preset is very strict, but it helps you keep your code consistent. If you disagree with any of the rules you can disable them globally in the .eslintrc file.

Create your code in the lib/ folder, create unit tests for it in test/ (pro tip: get code coverage by running yarn test -- --coverage, very cool!).

There are two ways of testing that your module code is working.

  • Bad: Installing it after you’ve published it
  • Better: Running yarn pack (creates a installable tar.gz file) and install it in a different project using yarn add /path/to/targz/file.tar.gz
  • Best: Using yarn link to create a symlink between your module and the project you are testing it in.

In your module project folder, simply run yarn link, output should look something like this:

yarn link v0.24.5 success
Registered "our-awesome-component".
You can now run `yarn link "our-awesome-component"`

In the project where you want to test your component, simply copy and paste the command shown by the output, e.g. yarn link "our-awesome-component". This will create a symbolic link in your test project at node_modules/our-awesome_component that points to your actual components code. Meaning that when you run yarn watch in your module project, the code will hot-load and will immediately be available in the test project, giving you a very quick feedback cycle.

When you are done, and your component successfully lints, all tests passes and it works well, you can move on to the next step, publishing it!

Publishing it to npm

Publishing is easy, too easy.

First things first, get your code ready. I like to delete the dist/ folder and re-run yarn build to make sure there aren’t any extraneous files in there.

Once your code is ready, you can publish:

  1. Create an account on npmjs.com, if you haven’t already
  2. Log in to npm on your command line using npm login
    $ npm login
    Username: karl.run()
    Password: ****
    Email: (this IS public) karl@karl.run
    Logged in as karl.run() on https://registry.npm.org
    
  3. yarn publish
  4. Input a version number, be sure to follow semantic versioning
  5. You have just published your module! The website should be instantly available on npmjs.com, ready to be installed by millions of developers.

PS: Your first set of downloads is going to be a set of npmjs mirrors, scrapers and analyzers that will fetch your package every time you publish a new version. 🤖

If you disagree or I’ve written anything erroneous, please let me know in the comments or via twitter/email.