Docs are an Engineering Product

why wikis and blogs are a bad idea.

Adam Michael Wood

The Problem

Free and Open Source projects are notorious for incomplete and poorly written documentation.

GitHub’s 2017 Open Source Survey

“documentation is highly valued, but often overlooked”

“incomplete or outdated documentation is a pervasive problem”

Bad ways of solving the problem

  • wikis
  • simple static site generators
  • Markdown

“Good for non-coders”

  • wikis
  • WordPress, Drupal, etc.
  • Gitbook

“Good for developers”

  • Jekyll, Hugo, etc.
  • Markdown
  • Zero structure
  • Docs-as-code… sort of

So who do we want to enable?

Of course, now we have two different groups we might want to enable and really two different approaches. And neither one is good for docs, or — actually — the people we claim to be “helping.”


We want to enable everyone.

Docs-as-code, with real doc tools

  • A tool built for all the weird docs things you’ll actually need
  • A workflow that fits what devs are doing
  • Clear setup instructions for new contributors
  • Automate as much as possible to eliminate friction

Starting with developers

I don’t believe any amount of making it easier is going to persuade a documentation-disinclined developer to suddenly decide to do it.

The problem for most developers

in relation to documentation writing is one of priorities and incentives.


an issue of empathy.

Tools and Process Must Fit Existing Workflow

Wood’s Third Law of Documentation

Docs tools and docs processes which do not fit well into the day-to-day coding experience of the developer are likely to be neglected.
— Adam Michael Wood

And what about those non-developers?

Let’s refine that category to:

People who do not currently know the common processes and tools necesary to contribute code to an open source project.

Thinking about new contributors

  1. Their motivations for contributing.
  2. Our responsibility to form new community members.

Why do people contribute to open source?

Career goals


What benefit does a new contributor get from light-weight tools and weak processes that are disconnected from the developer experience?

New contributors want to learn how to do this stuff.

They don’t want to edit Wiki pages.

And then there’s our responsibility.

We must not fail to pass on the skills and values that are needed to perpetuate our communities.

Documentation provides a unique opportunity for learning

Contributing code is hard

If you have ever written code for an existing project, you know how onerous local dev environment setup can be.

And then… once you have all that set up…

finding your way around a new code base,

finding an issue to work on that is at an appropriate difficulty level,

dealing with infinite failure paths…

And then, on top of that, we need people to learn about


and GitHub

and how to branch appropriately

and how to initiate a pull request

and how to deal with merge conflicts

Docs are EASY

(Compared to all that.)

(If you do it right.)

Docs as code, but not as hard as code

So far…

  • better for experienced devs
  • better for new contributors
  • better for the community

For certain definitions of “better”

But what about the docs themselves?

From the abstract

Any project larger than a small utility library needs real documentation tools. “Quick” tools like wikis and Jekyll blogs contribute to documentation debt as a organizing, editing, and adding content slowly become more onerous and disconnected from the developer experience.

Here’s the problem with Jekyll

(and Hugo and VuePress and Next and Gatsby and Hexo and GitBook and Pelican and Nanoc and Nikola and Octopress)

Markdown sucks


More on Markdown being bad

Please read Why You Shouldn’t Use “Markdown” for Documentation by WTD Founder Eric Holscher.

And what I really don’t like about Markdown

It isn’t extensible.

URL-based cross referencing is fragile

What happens when sections move around?

No included integrity testing

Do you know about all your broken links?

Ad hoc plugins, template snippets, extensions, and mixed markup proliferate

Here’s some markdown…

{% include important.html content="We will assume that you have `apoctl` installed, configured and **you have a valid token** in the rest of the documentation." %}

<div class="boxcontainer">
{% include box.html
    title="Install apoctl"
    content="Aporeto provides a command line tool named apoctl. You will need it throughout all the documentation, so let's get it installed."
    link="installation_apoctl.html" label="Install apoctl"
{% include box.html
    title="Configure Docker"
    content="If you plan to install Enforcerd as a Linux service or run it as a standard Docker container, please follow these instructions before going any further. This step is not necessary for a Kubernetes or an OpenShift installation."
    link="installation_configure-docker.html" label="Configure Docker"

Consistency is a serious problem

The solution:

Use a real documentation engine that also supports a docs-as-code workflow.


  • Semantic, lightweight plaintext format (restrucuredText)
  • robust cross referencing
  • built-in consistency checking
  • typical documentation constructs
  • extensibility

Downsides to Sphinx

  • HTLM5 story is not great (captions/figures, for example)
  • plugin dev docs are not great
  • PDF generation is tricky, especially with tables
  • i18n and L10n aren’t amazing (but they are accounted for)
  • developers don’t like reStructuredText

Developers don’t like reStructuredText

But they don’t even complain about the right thing.


reStructuredText has some problems

But really…

Devs are just kinda lazy.

Which is bullshit.

Developers who pride themselves on knowing several different programming languages that have different syntaxes, paradigms, ecosystems, and tools somehow can’t be bothered to take ten minutes to learn reStructuredText?
— Adam Michael Wood

It isn’t that hard.

// Markdown
I can *italic* or **bold** some text, 
and [link to another page](/path/to/page#section-id).

// reStructured Text
I can *italic* or **bold** some text and 
:ref:`link to another page <section-id>`.

And sometimes…

// Markdown (sort of)

{% include note.html 
content="Some content of a note.<br><br>
Imagine if this was several paragraphs." %}

// reStructuredText

.. note::

   Some content of a note
   Imagine if this was several paragraphs


The overriding design goal for Markdown’s formatting syntax is to make it as readable as possible. The idea is that a Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions.
- John Gruber


Let’s make this a bit more specific, and talk about what we actually did at Open Data Kit…


  • git, Github
  • CircleCI (matches local via venv and make)
    • Proselint w/extensions (style checks)
    • Sphinx build (integrity and spelling checks)
    • deploy to…
  • AWS S3

Some neat things

Work we still have to do

  • Windows support is rough
  • automate more
  • refine style checks
  • testing our tools
  • automatic testing of procedures
  • (maybe) automate screenshots
  • A bunch of writing