Bootstrapping a JavaScript Library
Tags: javascript, node, library, opensource
Published: 2017-09-23 22:07:49

---
title: "Bootstrapping a JavaScript Library"
published: true
tags: javascript, node.js, library, open-source
canonical_url: https://monades.roperzh.com/bootstrapping-javascript-library/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/8dw2mlgcx8m1oh2w8x2z.jpg
---

_This post was originally published on [monades.roperzh.com](https://monades.roperzh.com/bootstrapping-javascript-library/)_

I felt compelled to write this because I've read many experienced programmers complain about the quality/quantity of npm packages in ways that are not helpful. Instead of providing a solution to the problem, this discourages new library authors to get started and this is unfair for the whole community: Imagine how many good packages we are losing! Imagine how many potential OSS collaborators we lost because they are worried about screwing up!

If you want to write your first JavaScript library, please don't be afraid, in this post I will try to walk you through the process.

## Philosophy

Before starting, I'd like to make clear that the main rule governing this guide is **simplicity**.

Writing and publishing a node package should be a painless process, but It's possible to go overboard with all the tools available to enhance your workflow. While these tools are extremely helpful, they slow you down at the beginning.

The premise is to **start small**, and add tools as you need them.

## Getting started

You'll need to have [node.js](https://docs.npmjs.com/getting-started/installing-node), an updated version of `npm` and Git. At the time of this writing I'm using:

- node.js v8.2.1
- npm v5.3.0

## Code organization

All the code is contained in a single folder:

```js
+-- mylib
|   +-- index.js
|   +-- test.js
|   +-- // other files
```

- The `index.js` file is the entry point of your application, this is what the consumers of your library get when they `require()` / `import` it.
- The `test.js` file contains your tests.
- There are other files lying around, all related to the configuration and documentation of your project.

_note: As your project grows in complexity you may want to organize the code a bit differently. In that case, the convention is to create a folder called `src` or `lib` to contain your multiple source files, and a folder named `test` for your tests._

For now, go ahead and create a folder to contain your project along with the `index.js` and `test.js` files.

## Creating a package

Every project has a `package.json` file, which contains metadata related to the project that is used by npm in order to identify the project as well as handle the project's dependencies; npm comes with a handy command (`npm init`) to help you generate your `package.json` in an interactive way.

When running the command, you'll be prompted to fill a couple of values that describe the project. Besides the basic stuff (package name, author, etc), there are two things to look at:

- Try to be thoughtful about the versioning of the package, when possible always try to follow [semantic versioning](http://semver.org/).
- The license under which you're making your package available. Jeff Atwood has a good [post on the subject](https://blog.codinghorror.com/pick-a-license-any-license/). The [MIT](https://opensource.org/licenses/MIT) license is a good option.

For now, leave the `test command` and `git repository` entries empty, you are going to fill them later. This is what initializing a project with `npm init` looks like:

```bash
Â§ npm init

This utility walks you through creating a package.json [...]

package name: (mylib)
version: (1.0.0) 0.1.0
description: This is a short description of my library!
entry point: (index.js)
test command:
git repository:
keywords: relevant, keywords, here
author: Roberto Dip
license: (ISC) MIT
```

If everything went right you should have a `package.json` file at the root of the project.

## Version control

If you are not sure what version control is or why you need it for your project, please read this [tutorial](https://www.atlassian.com/git/tutorials/what-is-version-control).

### Ignoring files

> Version control is intended for files that people edit. Generated files should not be committed to version control. For example, do not commit binary files that result from compilation, such as .o files or .class files. Also do not commit .pdf files that are generated from a text formatting application; as a rule, you should only commit the source files from which the .pdf files are generated.

_Michael Ernst, [Version control concepts and best practices](https://homes.cs.washington.edu/~mernst/advice/version-control.html)_

You tell Git to ignore certain files in the project by creating a file called `.gitignore`. This file contains series of patterns letting Git know which files or folders you don't want to track.

There are [multiple](https://github.com/github/gitignore) [templates](https://www.gitignore.io) out there if you're lazy to type, but for now, this is more than enough:

```bash
# Temporary files created by OSX
*.DS_Store

# Files related to development
node_modules
```

### The first commit

Since you have done progress, it is a good idea to start tracking your changes. First, init your repository:

```bash
Â§ git init
Initialized empty Git repository in projects/mylib/.git/
```

Now add and commit your files:

```bash
Â§ git add .

Â§ git commit -m "Initial commit"

[master (root-commit) 88b12fb] Initial commit
 2 files changed, 18 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 package.json
```

## Testing

To set up your test suite, you need:

- A library to perform assertions. At least for now, the built-in [`assert`](http://nodejs.org/api/assert.html) is more than enough.
- A tool to run and report assertions. I like the simplicity of [mocha](http://mochajs.org/)

_note: If in the future your tests grow in complexity, you can switch to any of the magnificent test libraries that JavaScript has._

### Setting up mocha

The only thing you need to do is to install it via npm:

```bash
Â§ npm install --save-dev mocha
```

To make your life easier, you can run tell npm how to run your tests when you type the `npm test` command by filling up the test script in your `package.json`:

```json
"scripts": {
  "test": "mocha"
}
```

_note: There is no black magic here, the `scripts` object allows you to define arbitrary commands with `npm run <command>`, since the test command is used so frequently, npm allows you to omit `run` and call the test command directly._

### Writing your first test

In your `test.js` file:

```js
// Require the assertion library
const assert = require('assert')
// Require you library
const mylib = require('.')

// Describe you library
describe('MyLib', function() {
  describe('#hello()', function() {
    it('should return a string representing a greeting', function() {
      assert.equal(mylib.hello(), "Hello!")
    })
  })
})
```

And now, run the test with the command that you have previously defined:

```bash
Â§ npm test
```

If everything is right, the test fails (what a strange thing to say). This is because your library needs to export a `hello()` method. Open `index.js` and define it:

```js
module.exports = {
  hello() {
    return 'Hello!'
  }
}
```

And now the tests pass. The important thing to note here is the fact that you can easily require and invoke your library's methods, allowing you to test different outputs. It is always a good idea to cover as many edges as you can, this will make your code more solid in the long term, and will make you more confident when making future changes.

As you have done more progress, you should commit those changes:

```bash
Â§ git add .
Â§ git commit
```

_tip: it's not always a good idea to `git add .` and `git commit` right next, I encourage you to check safer alternatives like adding [`git diff`](https://git-scm.com/docs/git-diff) and [`git add -p`](http://johnkary.net/blog/git-add-p-the-most-powerful-git-feature-youre-not-using-yet/) to the mix._

## README

In the README you let the world know what your project does, how to contribute, how to use it, and any additional information that you want your future contributors to know.  [A Beginner's Guide to Creating a README](https://changelog.com/posts/a-beginners-guide-to-creating-a-readme) is a good source to learn how a good README looks like.

While you have the freedom to write it in any format, the standard format is [markdown](https://en.wikipedia.org/wiki/Markdown). If you're having a hard time with the syntax, [here is a tutorial](http://www.markdowntutorial.com/lesson/2/) and here is a [complete reference](http://commonmark.org/help/).

_tip: [dillinger.io](http://dillinger.io/) is an online markdown editor that lets you preview what are you editing in real time._

_note: some project files are named with UPPERCASE letters. This is an old convention that I've decided to stick with, the rationale is that makes the files easier to find for somebody new in the project._

Once you have a README.md file, don't forget to commit:

```bash
Â§ git add README.md
Â§ git commit -m "Add a README"
```

## Publishing

### The source

As soon as people start using your package they will find bugs, improvements, new features, etc. (that's the beauty of open source software). So, it's a good idea to make your code public to the world, allowing other people to contribute.

You can do this through Git, publishing your repository in a hosted git server like [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/) or [Bitbucket](https://bitbucket.org/product). It doesn't really matter where the project is hosted, you can always switch later on.

In order to publish the source you need to:

1. Create an account in any of the services mentioned above.
2. Create a repository.
  - [Instructions for GitHub](https://help.github.com/articles/creating-a-new-repository/)
  - [Instructions for GitLab](https://docs.gitlab.com/ee/gitlab-basics/create-project.html)
  - [Instructions for Bitbucket](https://confluence.atlassian.com/bitbucket/create-a-git-repository-759857290.html)
3. Grab the URL of your repository and push your changes.

```bash
Â§ git remote add origin [your-url-here]
Â§ git push origin master
```

And since you have your repository URL at hand, fill the `git` entry in your `package.json`:

```json
{
  "git": "[your-url-here]"
}
```

### On npm

While publishing sounds scary, the process boils down to:

1. Login (`npm login`) or register (`npm adduser`) as npm user.
2. Run `npm publish` to publish your package.
3. Enjoy!

There are more detailed instructions at the [npm docs](https://docs.npmjs.com/getting-started/publishing-npm-packages).

## Final Thoughts

The idea of this guide is to get you started developing your package. As for distribution is concerned, the process may vary a little based on which environments you want to support (node.js, the browser or both). By following this guide your package will be ready to run on node.js **or** the browser (depending on how you write your code). If you want to support both environments [check](https://github.com/umdjs/umd) [out](http://www.matteoagosti.com/blog/2013/02/24/writing-javascript-modules-for-both-browser-and-node/) [these](http://www.matteoagosti.com/blog/2013/02/24/writing-javascript-modules-for-both-browser-and-node/) [resources](http://www.richardrodger.com/2013/09/27/how-to-make-simple-node-js-modules-work-in-the-browser/), and if you still have questions feel free to reach me on [Twitter](http://twitter.com/roperzh) or [email](mailto:rroperzh@gmail.com).