The Essential Sections for Better Documentation of Your README Project

  • November 20, 2019

Most of my days, I read documents—software sources—then write code. README files are my entry points to “feeling out” new software before deciding if I would like to introduce them to my codebases. Without these non-eventful pieces of markup rendered as HTML, I wouldn’t be able to develop web and server applications with such ease.

All I expect from a README file is—within a single page— for it to provide me with the content I need to get started and to obtain a result. I will read it more in depth as I gain more experience using the software when I stumble on problems I am unable to solve on my own.
When I read files such as fathom“a framework for extracting meaning from web pages”—I struggle to engage with it. I can sense it’s good software but all I anticipate are additional barriers.

In this article, I will summarize the appealing and essential things about README files I have found over time, as well as the common pitfalls that have slowed me down.

The article is written from the perspective of a full-stack JavaScript developer—your experience may differ, but I hope you will still be able to learn a few ways to improve the essential piece of documentation README became.

Table of contents

  1. The history of README
  2. The general expectations of a README file
  3. The usual sections and inspirations
  4. References and other resources
  5. Useful tools
  6. Credits
  7. Contribute

1. The history of README

Did you know that the first README text file we know of was published in 1974? On November 27, 1974, to be precise. It states that it is the documentation of some Fortran commands for PDP-10 mainframes, during the time a single computer would require a space comparable to an actual data center room.

In the early 1990s, README became a tad more interactive, with the introduction of the man UNIX command—man for system manual. This adds system-wide access to software documentation—a program is installed alongside its user manuals—and structure.

By structure, I mean visual structure—headlines, text formatting (bold, italic, underline)—as well as content structure, with mandatory and optional section names.
One could provide different user manuals for a given software: For the command line interface, for library calls, for system calls, and even for data formats!

Even though a manual and a README file are different per se, they share common roots: They improve software usability. They certainly have benefited from each other. They are also both embedded within the distributed software, requiring no additional connectivity beyond their installation.

However, something changed with the rise of GitHub and the fall of SourceForge in the first decade of 2000: The README file became the first content to be displayed when browsing a repository. In 2007, the first GitHub repository’s README was not something we could call astounding—especially considering what the author of this README Driven Development blog post has to say, but it is something to note.

Soon, the Markdown syntax’s popularity spread through this documentation front gate. It took a couple of years to become a de facto standard markup for README files—a popularity propagated by strongly rising programming ecosystems such as JavaScript. Other platforms (such as gitlab.com, npmjs.com, crates.io) mimicked GitHub by displaying the content of a module/package/repository README as the main content, too.

2. The general expectations for a README file

So what can we expect from a README file, more than 25 years after the first one appeared?

Writing a README file is not as straightforward as it sounds, and it requires some consideration and effort to make it legible and useful for readers. This section is intended to dismiss some expectations about README files that have built up over time—inspirations will come next!

image

An example of a Markdown redacted README rendered in HTML

Who is it for?

As weird as it might sound, have you considered the audience of your introductory piece of documentation? If you picture in your head several people you know who would stumble on the README when they get a copy of your software, are they the same kind of people as you? If some will use it to fix bugs, and others to customize its interface or simply in their daily lives, they have different needs, and therefore will read the README differently.

Put simply, a code contributor, an end user, and a designer all have different skills as well as different expectations when they browse (software) documentation.

The ReLaXeD PDF generator is well aware of this, as it offers relevant sections for contributors—people skilled to tweak the plumbing of the software—and for users, that means the people who would generally mostly master HTML and CSS.

I tend to proofread README files with a colleague or friend I value for their honest feedback. What they see as good are highlights to me, while what they do not understand, the bits they find confusing, or the mistakes they spot, show where things need to be improved. A smooth reading requires both dedicated writing and active listening.

image

Repository badges convey information as well as densify the presentation of multiple data at the same time

Formatting

Gone are the days of README files being displayed with a monospace font over 24 rows of 80 columns. Formatting options were sparse, almost to the point of being nonexistent. Modern README files have access to all HTML5 features, although only its most common features are part of the Markdown syntax specification.

Headlines, strong emphasis (bold), hyperlinks, and lists are four easy formatting features at our disposal to add contrast to our content, by making words more prominent and spacing elements out.

Some HTML5 tags can be added with very little writing and reading overhead. Some of them have interactivity built in, such as the <details> tag, as seen on the below libphonenumber-js library:

image

libphonenumber-js’s interactive way of folding and unfolding content details

Text alignment can be part of the deal if you concede to wrapping your paragraph with a <p> tag and adding an extra style attribute. Take the following example of centering baseline text below a headline:

# Example.js
<p style="text-align: center">A JavaScript library to add more kilobytes to your front-end applications.</p>

Structure

The structure of a README file conveys many cues to both regular and new users. Headlines will serve as signposting, and will reflect how careful you are, not just with code, but with words, too. A bit like with a news article, general information is implicitly located at the start of a document, which is then followed by longer bits, and some less-compulsory content not far behind. You start by answering questions and then go in depth, closing with gentle information.

Tables of contents are great for providing a bird’s-eye view of your content. The eslint module makes good use of it to let any kind of audience start with what makes most sense to them. And they have great headlines, too, the kind of content that reassures me about the maturity and ease of use of this tool.

image

An example of table of contents within a README file

If a README file is linear by design, the human brain is not. A table of contents is one example of a navigation compass. Hyperlinks are jump springs for navigating previous or the following parts of the same document, even to other files. Create a dedicated section and refer to it several times to clarify what your software has to offer.

A headline depicts the content of a section—for example, an action, a software API method, or a message to the user. A question (“What is it for?”) will resonate with the reader’s state of mind, whereas a bland label might be “invisible,” in a way—“Description” is not always as explicit. However, complex or multipurpose API methods can benefit from a descriptive headline, as illustrated with the nock testing module:

image

Example of headlines showcasing variations of use of a similar function call

By the way, short size README files are fine, too, and the husky module is a good example of that. You get the gist in only a few lines, before being helped by various guides and resources (see some more examples about these in the “Guides and resources” section).

image

Example of a concise README file, showcasing usage, configuration, and installation that can be read in seconds

Finally, if section naming is done well enough but the target audience is ambivalent (see the “Who is it for?” section), it will not prevent the reader from being confused. I struggled with the AtJSON module: The README file named the sections well—they even use questions as headlines—but they address a self-designated standard, then object shapes, then how a document is processed, before ending with an example… Which is the main object of this repository.

Make sure you check out the “Usual sections and inspirations” part of this article to find out more about this topic.

Voice and tone

I discovered that carefully choosing words is a thing when I stumbled on Kate Kiefer Lee Voice & Tone guide at MailChimp. Still human-sounding, despite being designed by government agencies, the 18 Fellows voice and tone and UK’s Digital Government Services writing guides are other examples of how words can depict things for you.

I cannot tell what your voice should be, but personally, it makes me feel good when the wording seems sincere and cares about not letting me down on the way. The way the eslint README and the “How do I create a new document” section of AtJSON are written make me feel like real humans are behind the words and the code, and I can get in touch with them if I need help. It reassures me to know I won’t be turned away by some pedantic criticism about a missing semicolon.

Words such as “easy,” “obviously,” and “simple,” and expressions such as “everybody knows,” have a high potential to make people feel stupid. The writer can hardly assess whether something is easy, obvious, or simple for others. Being friendly, sincere, and relatable by your audience requires a bit more courage than writing a couple of words.

Who do you want to be when you sit next to a user and read the README file out loud? Maybe that will provide you with some guidance on how to write to this person and the rest of your user base.

Visual cues

Formatting content and having a clear structure can be complemented by visual elements. They convey more information on a small surface and become eye-catching when repeated—writing has its own design patterns, after all!

When the outcome is related to a computer interface, the quickest way to get a reader to the outcome is to display a screenshot of your software—either a static or animated one. One or many images work, either to introduce or to highlight key aspects of a program. Have a look at Refined GitHub, ReLaXeD, and RunJS, for example. With the last suggestion, the screenshot clarified what the repository was about, and without it, I would not have figured out that it was a standalone desktop application.

image

Example of screenshots displayed as a table layout

Tables are great for regrouping information and grabbing attention with a single word: A row with “Windows, Linux, macOS” will raise a question, which will be confirmed by rolling an eyeball up to the table header or its headline to get the context. The PowerShell README file makes great use of tables to present a multi-entry list of download links.

When the output of a program is textual—either words or structured data—a self-explanatory and very visual way of setting things out is to display a sample output inside a code block. I would have benefited from this to get an idea of the shape of data objects of the MoMa collection, for example—especially when the data files are too large to be previewed in the online source tree explorer.

Tips

I used to assume that README was a file located at the root of a software repository. Did you know a README file serves as an index file in any directory of your versioned tree? It is pretty handy if you feel the need to split its content, or if you want to address specific needs for relevant folders of your projects.

You get Markdown to HTML conversion for free with the GitHub API when you use its Repositories Contents API combined with a custom Accept HTTP Request header. Give it a spin to get an HTML copy of this article, using cURL in a terminal:

curl --header 'Accept: application/vnd.github.VERSION.html' https://api.github.com/repos/oncletom/behind-the-code-readme-article/readme

Or directly in your web browser, using the Developer Tools:

await fetch('https://api.github.com/repos/oncletom/behind-the-code-readme-article/readme', {headers: {'Accept': 'application/vnd.github.VERSION.html'}}).then(response => response.text())

Without the Accept request header, you would obtain a JSON response, in which the content field would be the Base64 encoded raw content of the README file.

Although I have only mentioned the Markdown syntax so far, other syntaxes might be more comfortable—or feature-complete—for what you have in mind. My favourite is AsciiDoc (.adoc or .asciidoc file extension), but you could also try docutils’ ReStructuredText() (.rst), Ruby’s RDoc (.rdoc), Textile (.textile), and even MediaWiki (.mediawiki).

Find out more about how GitHub processes a README file in the github/markup repository—wait for it—README.

3. The usual sections and inspirations

Now that we’ve dealt with general expectations, let’s dive into the value you can bring to your readers via some specific sections of your README file.

Description

Well, if the content part above the folder of a README is… self-descriptive, we can make an exception and not explicitly label our software.

But what is a description anyway? Probably something that states in a sentence or two what the program is about (“X is a Y to do Z”), and maybe a screenshot and some context, if applicable.

After the one-liner, it’s good to add more context—what the output is, what the inputs are, the browser compatibility, runtime requirements, and so on. That is, elements that describe what this is, and what this is about. It might seem obvious to you why you developed that software, or where these data come from, but that’s not the case for the people who are not the core audience of your work.

Also, if the repository is about a tool for transforming something, it is a good moment to refer to the syntax/specifications/user manual of that “something.” For example, Asciidoctor is a Ruby tool for converting AsciiDoc syntax into various formats, including HTML, but they never refer to the input syntax expected by the library, assuming you already know about the markup syntax, which is a shame because it makes it harder to use.

Usage

Writing is easy, but writing explicitly takes more effort—the “Usage” section is a great for clarifying what you could have missed in the description. Not only does it give a better overall picture, but it provides ready-to-use samples of code to speed up the process for any person who would like to get started as soon as possible.

franc README is remarkable in that way: Usage is shown sooner than later, it illustrates variants of use of function calls, and it demonstrates several user interfaces that you can obtain a result from.

Installation

Most of the time, the installation process should be straightforward: A single command line—if any—and that’s it! Installation instructions start when the user has a required environment up and running, and ends right before calling your software, either from the command line, a web browser, or a runnable program. Some packages’ installation processes differ, depending on the platform—this is a good time to remind yourself of the best way to get software ready to be used.

The Node.js sqlite3 module does a pretty extensive job of specifying alternate ways to install the package—especially from source, to take part in the compiled sources for your very own exotic hardware. An end user might know how to use an SQLite database on Windows, but not the inner plumbing of compiling C++ code on Linux, a potential target operating system for production deploys.

The more steps you need to install one tool, the more likely mistakes will be made along the way, and the more likely a user will take off if they can find an easier alternative. And that is something visible in a README file: I might not even run the instructions if I find them scary.

Contributors

Thanking is an act of kindness. Saying “thank you” can be easily overlooked, so imagine writing it as though the document represents the final effort needed for a project…

The “Contributors” section is all about the people who gave something to the project and make it what it is today: Those who provided eyeball time, brain juice, lines of code, who managed and triaged issues, improved the code coverage, and even stumped up money! It is up to you whether you thank only the major contributors, or include all the “minor” ones, too. Surely there is a software somewhere to build this list automatically based on the commits history.

If you are looking for a well-formatted “Contributors” section, head over to the entropic repository. It makes good use of pictures, tables, and emojis to describe the involvement of its community.

The “Contribution” section describes how to contribute. Contributions are pull requests, ranging from fixing a typo to a battle-tested feature, such as gardening the documentation, raising an issue, asking a question, running the communications outside of the code repository, and so on.
Some platforms, such as GitHub and GitLab, handle a CONTRIBUTING.md file—a README tailored for explaining the contribution process. It is displayed when a person opens a pull request, but bear in mind this content might be seen for the first time after someone has nearly finished their contribution, not before they get started.

Gnome project librsvg holds a pretty decent example: It states the obvious about where to report things, gives guidance on collecting debug logs, expectations about formatting commit messages, and so on.

Guides and resources

If the README file is the alpha of a project, it is certainly not the omega. Guides and resources are additional files, external pages, or related media that should be paid attention to in order to cover a specific topic (such as migrating from v1 to v2), to get more background (such as a conference presentation), or even provide more lengthy content (such as a live coding an article/video starting from scratch to running software in production). If you want to document a lot without bloating your README file, this is the way to go.

I particularly like how the sharp module keeps it README concise while providing extensive care to ensure its tool is useable. Among the resources, you can find hyperlinks for detailed installation steps, a Markdown-based API reference, and benchmark results, as well as a changelog. In other repositories, I found links to community forums, chatrooms, and StackOverflow tags to learn more about questions asked by other developers.

API

The “Usage” section cannot cover in depth what a software can do: This is what the API section is about. It works well for libraries, web services, and command-line software. It is meant to be a sturdy presentation of all the levers and switches of the program, all the keys to unlock its potential, in a very prosaic way.

For each API member—a class, a function, or an interface—a solid expectation is to describe the intents, the inputs (mandatory and optional arguments, object shapes), the output (object shapes), and eventually, an example of how to illustrate or clarify things.

Describing a public interface can be very very lengthy—you can count on the “Guides and resources” section to link to a dedicated page or website with an ease you would not find in a static README file. Lodash) does a great job at keeping its README simple while linking to a dedicated API documentation website, with per-version documentation, collapsible navigation, autocompletion on method names, as well as dedicated documentation on variants of the library.

License

README files are a convenient location to signpost the license in use for a given repository. The idea is to state the license name and to link to a dedicated LICENSE or LICENSE.txt file with the entire license content.

If you have no idea what a license is, or which license is applicable to your project, there are a few websites where you can find the most suitable one: https://choosealicense.com/ and https://ufal.github.io/public-license-selector/.

4. References and other resources

There are certainly more things to write about README files, and there are other resources available where you can create your very own idea of what your ideal README file is:

5. Useful tools

Here is a selection of tools I use on a regular basis, or I found interesting over the period of time I wrote this article. They can help to illustrate, preview, and highlight your work.

6. Credits

Thank you, Anne-Laure Civeyrac, for helping me through the whole writing process, reviewing, and being so patient with the need to extend deadlines.

Thank you, Noémie, Guillaume, and Sofia for reviewing the article and for your suggestions.

Thank you, Sam Thackray, for proofreading the article, fixing typos, and improving the phrasing of the content.

7. Contribute

Have you spotted a typo, would you like to fix a link, or is there something you’d like to suggest? Browse the source repository of this article and open a pull request. I will do my best to review your proposal in due time.

This article is part of Behind the Code, the media for developers, by developers. Discover more articles and videos by visiting Behind the Code!

Want to contribute? Get published!

Follow us on Twitter to stay tuned!

Illustration by Blok

Thomas Parisot

Full-stack JavaScript developer
  • Add to favorites
  • Share on Facebook
  • Share on Twitter
  • Share on LinkedIn

Follow us!

Craving for some answers? We all have career questions. Get inspired weekly.

And on our social networks: