Development icon

How to Write Better Technical Documentation

Jeff Wax, Developer
#Phase2 | Posted

In my last blog post, I hopefully swayed you to the light side, making you chomp at the bit to do more documentation. It’s quite easy to tell someone to do something, though, and never actually explain what you want. “Write better docs!” I say, and you happily point to your README file that now contains an outdated paragraph explaining what the plugin did three months ago.

This post is here to help avoid that issue by explaining what makes good documentation. Keep in mind: as with all projects, programming languages, and people, every case is different. I’m not saying that everything I say here will be 100% necessary in every single situation; it’s just what I’ve found works best. None of it is gospel truth, but merely an opinion.

Existence

The best documentation in the world… exists. I can’t stress this enough: you can’t document something better if you haven’t documented it in the first place. You may write bad documentation, confusing documentation, brief documentation, and weird, hilariously ill-conceived documentation. As long as you’re trying, your documentation may help someone in the future (especially after you rewrite it to be better).

I can only reiterate what I wrote in the last post: write docs as you create, jot down notes in a textfile or in the margins of your code, spin up a wiki page with thoughts and headers. Once you get into the habit of creating documentation, you’ll find that it almost creates itself.

Your main goal here is to avoid having a page that says “Docs coming soon.”

image that says Dev Tools and has a list of documents

Structure

Nothing impedes good documentation than poor structure. Even if you’ve written the perfect explanation, when it’s buried three pages deep in a section titled “Contact Us,” nobody (including you) will find it again.

Documentation with rigid guidelines and standards is easier to use. If you’re already working in a framework, library, or API that has set documenting standards, such as DrupalPEAR, or jQuery plugins, follow those. If not, you’ll need to develop or copy your own structure. The more rigid and standardized, the better.

The big question is how you tackle categories, form, and ease-of-use. Take some time to think about this before starting your documentation, even if it’s just writing down five or six subject headings and figuring out what should go under them.

When I sit down to create a simple README, I normally start with the categories that I have found the most necessary in all documentation, then fill out or trim as necessary: SummaryRequirementsInstallationConfigurationUsage, and Contact. I’ll go through how to make use of each of those below, but first I have a few general tips when creating your documentation.

First, make use of screenshots to show your process. If a user can conceivably interact with a user interface to use your application/module/API, make sure to show pictures as well as words, to help those who learn better by visual aids. Showing a button instead of describing it is infinitely easier.

A must is to use technical writing skills. If you’re typing a list of instructions, start each step with an action verb: “click,” “navigate,” “scroll,” “set,” “run.” If you want to include more than one action verb in a step, break it into multiple steps. Use precise language, full sentences, and indefinite articles. YourDictionary.com has some great examples of technical writing.

Finally, imagine the reader is a newbie. By assuming the reader knows next-to-nothing, you can ensure your entire readerbase is on the same page, and that everything is as easy-to-use as possible.

With that out of the way, here are the areas that I think most basic READMEs and overarching documents should cover:

Summary

A maximum of two paragraphs explaining what the application sets out to do. There is nothing worse than looking at a chunk of code, or an API, and being unable to determine if it’s what you want or not. Even if it seems like the title is self-explanatory, redundancy can only help you.

Requirements

Anything additional necessary prior to usage of the application. Always list everything necessary to run what you have created, assuming they are a new dependency. For example, you would not need to list “Javascript” as a requirement if you’re writing a jQuery plugin, but you would need to list jQuery itself, as well as which versions of jQuery work. Failing to do this properly will end in some a lot of hair-pulling.

Installation

How to get the application itself running. Even if it’s something as simple as “unzip this file into that folder,” write that down. This may be the first time a user has made use of a plugin like yours. If there are multiple ways to install your product, include as many as you can think of.

Configuration

How to tweak the product to a user’s specific needs. If a function, API, plugin, module, or application has a way to customize its behavior that you intend users to change, you need to document how to do so. This benefits even those who use the code constantly, as well: a handy reference for function parameters will save coders minutes or hours of time a day.

Usage

How and when the product should come in handy. If your product has a complex UI, this can definitely be the largest section, filled with those screenshots and lists of technical instructions. Organization in this section can quickly get very complex, but thinking in terms of “where most users will start” and ending with the minutia is best. For a backend interface of a CMS, for example, you’d probably start with what appears on the first page a user sees, followed by basic content and user management.

A large idea here is the bizarre and frightening concept of “examples.” Judging from a lot of docs that I read, plenty of developers don’t know what this is, when really it can be the single most useful part of documenting any sort of product. What are the use-cases of this function or product? Where might a person as a user need it? What specific situations did you create the product for? This is where you get to justify to the entire world what you’ve created: don’t waste it.

Documentation flow chart

Contact

Who to ask for more help. This should ideally be you, but it is also very helpful to add a link to your issue tracker, your project homepage, and any organizations that support the code. You should also leave a note stating that the software is no longer supported if you are no longer able to do so.

Comments

What makes a good comment? I have a couple of pointers:

Think about “why,” not “what.” A lot of times code can and should speak for itself, but unless I have read an entire code chain, from build to end, I often have no idea what the final purpose of specific logic is for. Commenting about the end goal of particular logic, where a variable will be used, or how a method utilization is important in specific instances, eases the understanding for any reader.

Explain every conditional and minor leap of logic. When your if-statements are as easy as “x > y,” you can trust that any casual reader will guess the meaning. But readers may not understand why you’re testing x and y. Having a simple line explaining your thought process will ease debugging and logic chains if that conditional isn’t firing.

Comment block every function. This should hopefully go without saying, and a lot of coding standards require it before they pass basic linting functions. There’s a reason: just as every conditional needs to be described for clarity, and just as every function name should be descriptive, function definitions need comment blocks to ease skimming the code. Describing what a function does allows a debugger to skip over parsing the entire function.

Write in full English sentences. Unless you are commenting something like a simple math formula, there is no reason not to use full English. I refuse to accept your excuses, and so will you when you’re staring at a commented line, asking yourself what “str fnc eat blob stor” means.

Update your comments, constantly. Existing documentation can be better than wrong documentation, but nothing is more frustrating than looking back up from a function to see the description to be completely wrong. This is the sticking point for a lot of comment haters, like Peter Vogel, and one I can’t deny: documents don’t update themselves automatically. Luckily, whoever is rewriting the code is already in there, and they have the best understanding of how the code is changing.

Evolution

Documentation is not only constantly going out-of-date, but by necessity it should be. It’s an inherent part of the technology business that our products are ever-changing, as well as the underlying tech. In the same way, our documents are as out-of-date as the last module in our repositories to be updated.

There is only one solution: updating the documentation.

Updating comments is easy, because developers are already in the codebase, making changes. Updating READMEs, wikis, HTML docs, APIs, PDFs: that’s all much more complicated and time-consuming. For the most part, they require someone to go out of their way to make changes.

A major issue I’ve encountered before is a lack of time. I don’t have a good answer to that, other than to suggest making it a priority. Organize your project teams to get together at a specified time to go back over documentation and make the updates. The more familiar a team is with changing their docs, the easier it will be for them to make the changes, and the less time spent.

The world of documentation is far too broad and all-encompassing for me to cover all of what makes good docs here, but I hope that something has struck a chord with how to update or just plain document better. The open source world needs better and more complete documentation, and like it or not, the fact that it’s open source means that everyone carries the burden of docs.

So document, and thank yourself later.

Jeff Wax

Jeff Wax

Developer