Documentation at source{d}

What we write and how we write it

Originally posted on the source{d} guide.

Our company has been a big believer in Open Source from very early on. Most of our repositories are visible to anyone in the world. We agree this is for our own benefit, but public source code is not enough to support and develop an Open Source community.

The goal of this document is to help source{d} engineers understand what pieces of documentation they should write for an open source project, and how they should be written.

The main audience of this document is source{d} engineers, but it might be a useful resource for many others inside and outside our company.

This document is divided into two sections:

  1. The first section covers somes best practices for technical writing which apply to any piece of documentation you might be writing.
  2. The second section lists the main documentation artifacts all source{d} projects should provide.

General Best Practices

People read documentation in order to achieve a goal. Whenever you write a new piece you should keep their goal in mind.

For instance, you’re currently reading this document. What is your goal? Maybe you want to improve the documentation of your own project, or perhaps you’ve been told this is an awesome document and your goal is simply to enjoy reading a beautiful text of astonishing beauty.

On the other hand I know you’re a developer, so there’s no point explaining what source code is. That would seem patronizing or a waste of time.

I also know that most of us don’t speak English as a first language. Unnecessarily complicated words or sentences are then an obstacle to our communication.

Finally, I know you’re a diverse group. Among the readers of this document you’ll find people everywhere in the gender spectrum, different races, and different sensibilities. I do not wish to alienate any of them, so I need to be careful with the words I choose.

All of these concrete examples can be boiled down to the following best practices.

State a clear goal

A piece of documentation has a clearly stated goal and audience.

For instance, a README.md should be an overview of the project, maybe including some basic usage instructions. On the other hand CONTRIBUTING.md should cover what contributors care about.

Do not make a first time visitor read through how to contribute a project before they understand what the project is about.

Define a scope

As Carl Sagan famously said “If you wish to make an apple pie from scratch, you must first invent the universe”. Would you start an apple pie recipe with quantum physics? Hopefully not.

Same goes for documentation. You need to define the scope of concepts that deserve to be explained in a document. Those considered either too advanced or as prerequisites should be ommited. You can always link to some other document explaining them.

For instance, if a project uses Go and gRPC feel free to link to the homepages of those projects. Do not use more than one short sentence to explain what Go or gRPC are.

Keep it simple

Short sentences win. Avoid having overly complex sentences. It might seem weird at first. You might find the resulting text immature. But keeping your sentences short help the readers, and that should trump everything else.

Following the same logic, avoid overly complicated words.

As a rule of thumb, sentences longer than a printed line are probably too long.

Don’t alienate the reader

Avoid gendered pronouns. “He or she” should be rewritten as “they”. There is no reason for your document to make assumptions on the reader’s identity.

Avoid sexist connotations. For instance, “mom-proof” implies women are not technical. Tell that to Grace Hopper. You can read more about sexist language and how to avoid it here.

Avoid ableist language. Avoid words like “crazy” or “insane”. More on ableist language here.

In general, if someone would find what you wrote offensive it’s time to change it. There’s no excuse to offend anyone in a technical document.

Take accessibility in mind

It is probably impossible to write documentation that is fully accessible to every single person in the world. This doesn’t mean we should not strive for documentation that is as accessible as possible.

Many readers might have different degrees of visual impairments. While using images avoid attaching meaning to colors that are traditionally hard to distinguish. You can read more on what color combinations to avoid here.

For more extreme cases the user will not be able to see the image at all. Take that into account and try to add captions explaining the image where possible. At least make usage of the alt attributes on HTML and markdown.

Documentation Artifacts

Now that we’ve covered how to write, let’s talk about what to write. This section lists the pieces of documentation we care about at source{d}.

README.md

The README.md file in the root of your repository is the entrypoint to your project. At this point you still don't know whether the reader is a new-comer, an experienced user, or the most prolific contributor.

Give an overview of the project goal and its current state. Is this a demo, a library, or maybe some tool? Should it be used in production? Is too soon, or maybe too late because it’s been deprecated?

Is this code distributed in any other way? Docker images, aptitude packages, installation scripts, etc. should be mentioned here.

For tools, it is also worth including basic installation instructions. If the instructions are long they should be part of a different document linked from this one.

This document also serves as the index for all other documentation. README.md can also be found in folders other than the root of the repository. In that case it should document what the subtree below the folder contains. This is useful when you have libraries and binaries in a single repository.

A README.md template is available here.

TL;DR:

CONTRIBUTING.md

This document describes what contributors should know in order to contribute to the project.

This document should contain all the details required for anyone to send a contribution. It often contains instructions on how to build the project from source code and validate the source code by running unit and integration tests.

This is also the place where style guides and other code conventions and requirements should be documented or at least referenced. Examples of these include code coverage requirements, adopted unit testing frameworks, and documentation conventions.

A very good example of CONTRIBUTING.md is the one from angular.js.

If you’re starting from scratch, considering using this template.

TL;DR:

Reference material

This is the documentation that users will reguarly consult while using your project. The actual form depends on whether the project is a library or a tool.

For libraries, this document tends to be autogenerated from source code. Tools like godoc, javadoc, etc. provide an easy way to do this. For tools, the document will be often hand written, think about man pages.

In both cases, this kinds of document tend to grow quite fast as they provide detailed information on each feature and the feature’s options. They do not require a sequential structure. Users often search and read single section. Therefore it’s recommended to have a good table of contents and search features when possible.

TL;DR:

  • Audience: Users of the project.
  • Content: List of all of the features of the project with full information on arguments, flags, and others.
  • Example: https://docs.angularjs.org/api

Release Notes

Every new release of your project should be versioned following semantic versioning principles. Each new release should come with release notes. These notes are not a list of every single PR and issue that have been closed during the release. Instead, the document should explain what are the most important changes in the release, such as critical bugs, breaking changes, or new features.

TL;DR:

  • Audience: Contributors and users of the project.
  • Content: New features, bug fixes, and other relevant changes since the previous version released.
  • Example: https://golang.org/doc/go1.9

Guides/Tutorials

For complex tools it is sometimes useful to write guides showing how to perform some specific use case. These guides can be short and useful for early beginners, also known as quick starts. But often we want to show a complex use case, or show how the project interacts with other technologies. In that case we will write a tutorial, or even a codelab if we want the readers to put the concepts to practice.

All of these documents have a goal in common: teach how to do something. They follow a step-by-step structure. Users often read these guides from top to bottom, unlike reference documentation.

TL;DR:

Code of Conduct

All projects under the source{d} organization should mention the Code of Conduct available in https://www.contributor-covenant.org/.

You can simply copy paste this markdown into your README.md and inside .github/CODE_OF_CONDUCT for each repository.

# Code of Conduct
All activities source{d} projects are governed by the [source{d} code of conduct](https://github.com/src-d/guide/blob/master/.github/CODE_OF_CONDUCT.md).

TL;DR:

Issue templates

Following the same philosophy of good documentation, good issue templates help users and contributors interact more efficiently.

Consider adding a ISSUE_TEMPLATE.md file either under the repo root or a direct descent of it named either .githubor docs. (More info here).

Consider using this template.

Other pieces documentation

Many other pieces of documentation are possible: from design documents to workflow descriptions or UML diagrams. Whenever you’re working on one of these pieces keep in mind your audience and their own goals when reading the document.

Resources