JavaScript Documentation Sucks

I want to use your JavaScript library. I really do.

Unfortunately, a lot of you are bad at documenting it, so I can’t figure out how to use it before I give up and find something easier to learn.

If you use docco, this is because you write your documentation in the same way you write your code. Like a good team hacker you write your code with the principal design goal of making it easy for the next person working on the project, and only after satisfying that do you write for the other decidedly more mechanical audience. You strive to structure your code so that new functionality can be bolted on, or bits and bobs twiddled with to make the whole thing faster, and only serving the goal of getting the computer to do work in as elegant a manner as possible. This is awesome. Maintainable and readable code is awesome. In an effort to make it even more awesome, you start leaving some comments around. You say to yourself, well golly gee shucks, it would be nice if I had a reminder that this function’s boolean argument indicates this or that; or maybe it would be nice to remember what all these RegExp back-references which I’ve rarely used before actually mean.

The problem is this: these comments are oriented at someone trying to understand the code, not just use it, so when you pull them out, they document how the code works, not how to use it. Someone looking to know how to use a function cares not that it calls out to something which takes a boolean parameter. Someone looking to instantiate a class to get work done cares not that some part of it uses a RegExp to accomplish its tasks. What someone does care about is the API that class or function exposes, and what work it does that is helpful. The whole point of abstracting something useful into a library is that I don’t have to write that code myself when I use it, instead I can understand only the surface of it, and rely on you to have done a good job implementing the thing. I don’t want to have to read through the whole piece of code to understand how to call into it. You’ve structured it for a developer looking to change it, not to use it, so I get lost, and your explanatory comments usually don’t tell me function signatures or typical ways I might call them. It doesn’t make sense to make someone who wants to consume your library have to traverse your one monolithic HTML page to find the one stupid function signature they are looking for.

So, for things that aren’t quick and dirty, or aren’t exhibitions, I don’t like docco. If you want to generate awesome docs meant for consumption by people hacking on the project, by all means, use docco, à la pow. I really don’t like people thinking docco or dox can be used for API documentation however. I believe this was never its intended purpose, but it certainly has been repurposed for this. Perhaps developers feel that docco and company are suitable for creating API documentation because they, along with JSDoc, are the high visibility tools available in the JavaScript ecosystem. The misappropriation of docco isn’t rampant but the problem is even more insidious than just this. There are some who go the opposite route and orient their comments for consumers using tools like JSDoc. I desire to have JavaScript libraries documented so I can use them, and the idea of a common tool like RDoc (and YARD) giving us something like rdoc.info would be amazing but for me, JSDoc is not the answer.

The problem again, is this: when you orient your comments at consumers, development becomes simultaneous development and documentation, which is just plain unpleasant. I think it’s absolutely insane to have a 10 to 1 comment to code ratio in a file. It is outrageous to expect developers to work in files where each function has been meticulously explained, with all the available options listed and explained, as well as numerous examples of usage, all in a comment block just above the definition. Class bodies end up being enormous, and you can’t fit a function body and the body of those called in the first body on the same screen. I find scrolling through the grey molasses terribly inefficient when trying to reason about or work on the code at hand. I cite the Rails source, or at least the portions of it which expose APIs aimed at developers, as an example of how challenging it is to navigate code with inline documentation. You just can’t write clear, concise, readable code, at the same time as writing exhaustive, useful documentation when they co-exist in the same file.

You may say, Harry, these comments are wonderful, because we will change our comments when the code changes; they are right there, they will be in sync! I absolutely concede this: the closer the words for humans are to the words for the computer the easier a job we will have of keeping them accurate during change. Harry, you might say, now I can declare the types I expect my arguments to have and people can provide them. Harry, smart IDEs could even verify these types! I can almost pretend its a statically typed language! Again, you have a point, this information is valuable both to the library hacker and the library consumer, and maybe some IDEs I don’t use are smart about the @param declarations. Harry, you say, use an editor where you can ignore comments or fold them. I say back at you: vim folds are hard, and I am lazy, and I’m not always in my own editor where I know how to fold.

To me, the clutter is simply not worth the advantages. We should design code such that the next man or woman coming along can edit it and succeed. We should not sacrifice their chances of success by making them work in and around the screen filling comment blocks. The code is the uniquely canonical specification for how it can be used. It implicitly declares all of its use cases, but it doesn’t have to go ahead and be explicit about all those use cases by talking about them at length inline. It is essential that these examples and signatures and use cases are found somewhere, but I make the conscious decision to move my consumer documentation out of the code such that the code can be clear and unencumbered. Some project owners create gargantuan READMEs, or HTML guide style documentation, or GitHub wikis that these signatures and examples and whatnot look amazing inside. The shining examples from my world are the Django docs, the Rails Guides (and recently the SproutCore guides), and inside the JS world the Mongoose, Express, and Testling documentation sites. These are all curated sets of words for humans as well as code examples for humans showing how to consume a piece of software in another one. The problem comes down to actually creating these words, and continuing to maintain them after they’ve been released. APIs inevitably change, so docs inevitably go out of date. The worst aspect is that developers may not make changes because it is twice as much work as it might be normally. You must write the test, write the code, and now find all the places that code you changed is referenced in the docs and change them. There are of course notable exceptions, but in the JavaScript community I find myself learning how to use something from its README, and then spelunking in the code to find out the nuances.

This situation may not be as dire as I make it out to be, because if it were better tools would have evolved. It often seems to suffice in our community to ask people to read your tests or Google every second thing to figure out how to do it. Those amazing library authors who have the self control to document seem to either publish annotated source, write enormous comments, or pour their hearts into markdown’d READMEs and static sites. The annotated source isn’t a good reference for consumers, JSDoc block comments impede development, and the README’d source can fall out of sync easily, as it has with my principle project, Batman.

So, I ask you, what is a JavaScript developer to do? How do I let people use my project, while developing unencumbered?

I would like to know, but I also have my own storm a'brewin. The solution is underway but can be found here: https://github.com/hornairs/percolate.