Documenting Javascript Projects

With JSDoc, Flow, and Documentation.js

this article was originally published on my Medium blog

We all (hopefully) know how important good documentation and reference material is to a successful software project. Without good documentation, a particular library may be next to impossible to use. Without a reference to how different components and methods work in isolation, let alone examples of how all the different pieces of a project fit together with each other, we are left to interpret the original intention of the author merely by reading the original source code, or if we are lucky, reaching for StackOverflow and googling random error messages. If this is an in-house or small project, you are probably completely screwed. Enter the copy-pasta black magic voodoo approach and hope that everything works as intended!

Contrast this with well-established projects that have great documentation, and the experience is quite the opposite. Stripe’s API documentation, for example, is not only clean and pleasing to look at, but easy to navigate, and is completely annotated with examples in 8 separate languages in how to properly interact with their developer API. Want to know how to create a new customer? Sure! Which language do you want to write the code in?

This level of robustness becomes necessary with huge, publicly consumed projects such as Stripe payments, but may not be necessary for your in-house or smaller projects. This doesn’t meant that you get to skimp on documentation! It just means that our goal for documenting our personal projects should be to get the most bang for our buck. The way we can do this is by properly commenting our code and leveraging existing tools in the Javascript community to give us nice, useful documentation with the least effort required.

In this article, we will be going over how to use two different tools, namely JSDoc and Documentation.js, to get nice, coherent API-level documentation for your Javascript code with minimal effort. At 4Thought Studios, we’re a big fan of using Flow, so we will throw that in too to make things even smoother. In an effort to be as useful and brief as possible, we will not dive into the full syntax of JSDoc, but its worth saying that THEIR documentation (although not pretty to look at) is very readable and worth spending the 20 minutes or so to read through at least once.

JSDoc

JSDoc is a standardized way of writing comments in your code to describe functions, classes, methods, and variables in your codebase. If you are familiar with JavaDocs, or any derivative (like those available in the PHP world) then JSDocs will be familiar to you. The ideas is that we describe how our code works with a few special keywords and formatting conventions, and we can use a parser to run through all of our commented code and generate nice, readable documentation based off of the comments we write.

What does this look like in practice? Here’s a short example:

So what’s going on in this example? Well, we first signify we are about to write a special JSDoc comment by starting the comment with /**. Starting with just one star, or adding a third star tells JSDoc to ignore the comment entirely — so pay attention to the number of stars!

Next, we write out a brief description for the function we are documenting in plain English, so someone reading through our code or API documentation understands the function’s purpose in the codebase. Finally, we annotate our two parameters as a number, as well as annotating our return as a number. And… that’s basically it!

We could get a bit fancier with a more complicated example, but generally speaking, this is as much work that you have to do when documenting your code. You could take things further and add an @example annotation, giving even more context to how this code should be used. But at the end of the day, this is as far as you need to go while documenting your codebase.

Documentation.js

Once your codebase is sufficiently documented, it’s time to reach for a tool that will help you generate documentation based on all the nice comments you just wrote. At 4thought Studios we use the fantastic Documentation.js project, but there are several more options out there if you prefer another route. All of these projects achieve the same thing — they translate your carefully written JSDoc code comments into readable html or markdown documentation.

Documentation.js is a node package designed to parse JSDoc and output your documentation in several different formats. We use Markdown so that we can link to the API documentation directly in our project wiki, but it might make more sense for you to output the docs as a fully-functioning website. Whichever approach you choose, you’ll have to introduce Documentation.js as either a system-wide or project-level dependency:

yarn global add documentation

(or npm install -g documentation if you prefer npm)

Then we can reference Documentation.js’s documentation (say that 5 times fast) to figure out how to parse our javascript files into readable documentation (I’m sorry for being repetitive — I don’t think that there’s any other way to say ‘documentation’).

documentation build path/to/your/javascript.js -f html

We use the documentation package to build documentation from the source file(s) specified, and format it as html with the -f flag. We could instead output the documentation as markdown, and to do this we would change the above command to:

documentation build path/to/your/javascript.js -f md

I know what you are thinking right now — this is all great, but does that mean I have to parse my files one at a time? This isn’t time saving at all!

Hold your horses — of course you don’t have to parse files one at a time! Let’s say that all of your javascript files exist in a src/ folder in your project. You can parse everything in one fell swoop:

documentation build src/** -f html -o docs

This will parse all of your javascript files in the src folder, and subdirectories, format it as html, and output the results to a docs/ directory. Pretty neat!

For bonus points, once you have the above command working as you want it to, include it as an additional script in your package.json folder to make your life easier in the future:

// package.json
{
  ...
  "scripts": {
    "docs:build": "documentation build src/\*\* -f html -o docs"
  }
}

And now you can refresh your docs by running:

yarn docs:build
\# or
npm run docs:build

Yay documentation!

Finally! A website that clearly communicates what the heck a development tool does!

Further Reading: