The Art of Documentation: How to Write Technical Documentation with Empathy
Documenting == A Game of Empathy
Documentation saves us a lot of time and hassle. Yet, many developers need to pay more attention to providing documentation along with their code.
In this article, I will share with you everything you need to know about writing documentation, with some quick tips on writing good documentation for your team.
Let's get started!
Why write documentation?
Documentation helps you provide context, gather feedback, and asynchronously understand concepts.
Have you ever felt confused going into a meeting without any clear objective? A meeting without an objective unnecessarily takes everyone's time because it feels like hours. People must explain the context multiple times for the audience to understand before getting to the main point.
Imagine onboarding an engineer without any documentation. It will take a lot of resources and time to onboard an engineer because every step requires another engineer to guide them. To streamline this, the engineer (buddy) who guides them should remember the onboarding steps and note it down.
Documentation can help spread your ideas faster and gather feedback. For instance, you want to implement a new feature that can be beneficial to the OKR of your team.
You realize that your PR has been up for a long time because it is missing the proper documentation and context for your reviewers.
Documentation can help your team and organization be more efficient.
Four Types of Documentation
Divio created a documentation system to help software engineers write good documentation. It characterizes documentation into four quadrants: tutorials, how-to guides, technical references, and explanations.
Tutorials
Tutorial is documentation that decides what a beginner needs to know. Your purpose should be a briefshallow overview, leaving all the details in the resources or links.
The important thing about tutorial-style documentation is that your reader should be in a position to start right away.
One of the best examples of such documentation is the Free Code Camp blog post, which teaches you how to manage state in a React App.
How-to Guides
In this kind of documentation, you can assume that the audience has some basic knowledge and understanding.
There is context at the beginning of the documentation with the assumption of what the audience should know. Then, it will guide the audience from point A to point B. Usually, a how-to guide doesn’t need to explain concepts.
One tip when writing how-to documentation is that practical usability is more important than completeness. For instance, you want to tell the user how to set up a React application. Although there are multiple ways of setting up a React application, you can explain one method in practice.
Technical References
Technical references are documentation on how to operate machinery.
They are meant to describe and are code determined - meaning they describe the class, function, and API and tell the audience how to use them.
This documentation is similar to how-to but different in that it mainly illustrates usage. Reference documentation should not explain concepts since it can make it hard to maintain in the future. Its sole purpose is to make searching for syntax information as easy as possible. Thus, many of these documents are boring or harder to read.
Examples, examples, examples
Writing this kind of documentation will be much easier to understand with an example.
An example of the Adyen API:
Some example sof technical reference documentation are Cats doc and Stripe API doc.
Explanations
Explanation documentation is explaining, illustrating, and clarifying a certain topic.
It is understanding-oriented.
Examples are project website, product level, or feature level documentation. This article is understanding oriented by telling you the different parts of the documentation and why they are important.
You usually see them discussing alternatives for implementation. For instance, you will discuss various alternatives and considerations for a feature design spike document used by multiple classes.
It may include diagrams to reduce writing a wall of text.
It usually states the general behavior and non-functional requirements.
Explanation documentation provides the bigger picture and focuses on context. Sometimes the audience doesn't need to understand why we do certain things, but providing them with an explanation can give some satisfaction and comfort that makes them happy to use your product/service.
Some examples of explanation reference documentation are the ByteByteGo Newsletter talking about payment systems, and the Slack Engineering channel discussing case studies about its architecture.
5 Stages of Communication
Documents are a way of communicating.
Based on different stages of communication, the way you project your message will also be different. Let's take a look at what I mean by that.
If we put communicate as a scale of feedback (like in the image below), you will see that questions asked in real-time communication will get instant feedback. On the other hand, real-life conversations could be more scalable - you can only relay messages to an individual compared to online docs broadcasted to the world wide web.
Real-life conversation: I get instant feedback on my questions and can relay my message to the other individual.
Phone call: there is some friction; I can’t see the person's facial expression, so I cannot gauge their emotion and feeling. However, a phone call can be more than two people - we can have a group call through Zoom.
Group Chat (Slack, Discord): this form of communication can be in real-time, but it is mostly asynchronous. When you post a question in a Slack channel, you are throwing your questions out into the wild and hoping that someone kind out there will answer them.
Email: we select to who the email message is addressed to, but we will not get instant feedback. We also need to find out if our messages was received and read.
Documentation: We preemptively answer questions in anticipation of what someone may ask.
These five communication stages are very important indicators of how you should write your documentation. You are writing the most scalable form of communication and the hardest one to construct. You will need to consider what your potential reader wants to know, in what scenario your reader will read your documentation, and how they feel when reading it.
What are some tips for writing Good documentation?
Think about the intent of your reader. It would be best if you changed the mindset from "What I can tell you?" to "How can they find the resource quicker?" Here are four simple rules of thumb for writing good documentation.
Pro tip: whenever you write, always read, write, reorder, prune, and repeat.
Always Give Context
Context saves your brain power to decipher some abstract piece of information.
The role of context is to bridge the gap between authors and their audience, strengthen the readers' comprehension, and preventing miscommunication of the writer's intent. Sometimes more is needed to know what your system does but also why you created such a system.
The Scala JSON Library Circe is one example of providing context in the documentation. It gives a quick start guide and prerequisite before using the library.
Cats Effect documentation, a Scala OSS library, has a Getting Started guide, which explains the prerequisite for importing the library into your project. Then, it explains the concepts behind their library for developers who want to know the "Why" of things.
Have you ever encountered someone who asks questions without giving any context?
"Has anyone ever encountered how to debug 'X'?
"Hey, sorry to bother you, but can I ask you a question?"
Just like asking questions, a lot of developers write documentation without giving any context.
In Scala, you can represent a type that contains either value with Either(link). The convention is to represent the failure type on the left side and the successful type on the right. To operate something unconventional in the Scala language, you must provide some context on those values. Or else, the API user may need clarification on the meaning of Left and Right values. I saw an engineer on our team create an API that returns an unconventional Left and Right value. Because the API developer needed to give more context, API users often questioned the function definition, wasting our team's time to keep explaining the context.
The prerequisite helps your entire documentation make sense. It helps guide your reader's interpretation of your documentation. Failure to write one will cause your reader to abuse the system. For instance, if you write documentation about the configuration override feature to solve any emergency hot fixes without context, your reader will abuse the feature by treating it as a fast way to build a quick prototype.
You don't have to write down all the content in your documentation. You need to link the prerequisite knowledge or API documentation to save your audience hours of confusion and searching.
Links and More Links
Keep your documentation short and sweet by providing links to the user to learn more.
If you project something confusing to the user, the best thing to do is to provide links.
The Circe(link) example said that you can put annotation @JsonCodec
in front of your case class. However, you must set up a configuration in your Scala build system. The documentation reference MacroParadise as a link for the reader to let the reader understand more about the topic.
You will often see a table of contents with links pointing to each section. This is a great way for the user to click on the location they want to read.
Some teams have a centralized documentation system. However, other teams may write their documentation across various software like Confluence, Jira, and others. With multiple documentation programs, I find it very hard to navigate between multiple tabs and sites to understand a concept. One way to solve this is by putting all the links on the README page. Thus, inside the README, you can easily find all relevant links to product documentation. Link to the repository owners' Slack channels and any important documentation that will help readers save time.
Instead of having a humongous README, you can separate the README into multiple sections, such as the Contribution.md for contribution guidelines, API_Doc.md for any API documentation, and Contract.md that will compare the behavior between legacy versus a current implementation.
The main idea of linking is saving your readers’ time. You are giving them links to point them in the right direction.
Avoid Passive Form
Active voice is more concise, direct, and easier for readers to understand.
Passive voice is considered wordier.
It is harder to understand "A String Y is returned from function X" compare to "Function X returns String Y."
Passive voice demands more effort because the sequence differs from how we usually make sense of events. The sentence structure is more complex. You let your readers spend valuable working memory on making sense of the sentence, and it decreases the likelihood of getting your main message across.
Write Documentation First Before Implementation
You get a clear bigger picture of what you should do, and so your documentation will be manageable.
Because you know little about the implementation, you will write your documentation more user-centric than developer-centric.
One tip I use before implementing something is to write documentation about how the user interacts with the system. Then, after writing all the statements down into a document, I directly copy and paste it into a test suite. Those documents serve as the initial test suite, which helps me write the implementation based on user behavior.
Many developers get too much into the details when they write documentation after the implementation.
Writing documentation with the implementation is also very hard to maintain because code changes all the time, but the user story doesn't.
Another important aspect of the documentation-first approach is that it helps you push your project forward much faster.
Conclusion
Documentation is more than just the engineering manager’s or tech lead’s job. Every developer and everyone in the organization is responsible for writing good documentation.
A couple of benefits of writing documentation are:
Make the team more efficient
Gather feedback and fast
Describe what's the meaning of “Correct”
Here is a short recap of 4 steps to writing great documentation:
Context helps make your documentation easier to understand.
Links are your friends when you want to provide more context.
Active voice helps make your documentation easier to read.
Documentation-first approach to development helps you keep your documentation up-to-date and easier to maintain.
What are some other tips that help you write good documentation? Please comment on them down below!
Have a great rest of the week, get some rest, and thanks for reading.