Software Documentation - Value, Misconceptions, Common Pitfalls, and Essentials
This article explores the value of software documentation, a few misconceptions about the need for documentation, and some common pitfalls we fall into when we document software.
Finally, it provides an overview of the essential documentation for software engineering teams and some guidelines for organizing documentation.
Introduction
Documentation is a hot topic in the software engineering world and has an arguably bad reputation.
Many engineers complain about the quality, the state, and the lack of documentation. At the same time, most engineers avoid and do not invest time in writing quality documentation.
Many engineers even hate to write documentation. Some engineers even consider documentation redundant and unnecessary. In contrast, some of them complain when they don’t find something when it is most needed.
In my early years as a junior software engineer, I have to admit that I also hated writing documentation. After all, “Why would an engineer write boring text to explain code instead of investing that time to write more code?”
Image by Maria Letta @free-gophers-pack
Well, through the years and my interaction with undocumented systems and codebases, I have become a big proponent of documentation. The pain, tears and time spent to find about undocumented requirements, specs, and designs were convincing enough for me to appreciate the value of good documentation.
In this article, we’ll explore thre following areas:
- The purpose of documentation
- Common reasons why many engineers don’t write documentation
- The value that documentation can bring in a software team
- Guidelines that have helped me when dealing with writing and maintaining documentation.
Purpose
Why should we write software documentation? What’s the purpose of software documentation?
Software documentation either explains how the software operates or how to use it, and may mean different things to people in different roles.1
Software documentation is like any documentation; it’s a form of communication. In software projects built by more than one person, communication is a crucial success factor of the software’s success.
Is it essential for everyone who wants to build, use, understand or interact with the software to have access to a knowledge base that can give an understanding of what they seek to find.
Common Misconceptions
This section, explores common arguments from engineers who refuse to write documentation.
Misconception #1: It’s not required; just look at the code
You don’t need documentation! Just look at the code!
This is a common one. “Why would you write documentation to explain how things work if the absolute source of truth is the code itself? Just invest time in providing better code readability”.
Image generated by gopherkon
Code readability is a vast topic and one of the qualities we strive for as software engineers. And it’s true, the most accurate description of what a software system does is the code.
But the purpose of code is to define behavior, not describe behavior.
The major problems with this argument are:
- Not everyone can read code. There are more roles than software engineers involved in producing a software system
- Reading code to understand the behavior of a system is not efficient and does not scale well with the increase in complexity and size
Not everyone can read code
Reading code is an option for software engineers who can read code. But what about the other stakeholders of the system who can’t read code?
A software team interacts with multiple stakeholders. For example, product managers want to clarify specific use cases. The technical support teams want to know just enough details to provide helpful information to customers.
Image generated by gopherkon
Without documentation, the communication overhead with go-to experts becomes too big to handle, and the team’s efficiency decreases significantly.
Reading code to understand a system is not efficient
Even if you can read code, software engineers that have not worked with the codebase can benefit from documentation. Before working with code, when we join new projects, we need an overview of the purpose of the system and the primary use cases it tries to solve.
Checking the codebase to extract the system’s behavior is possible but extremely slow and painful. It’s also possible to result in misconceptions about the behavior.
Remember ☝️, reading code is much harder than writing code.2
Finally, code readability becomes less and less valuable, especially for troubleshooting, when the complexity and size of a system increase over time.
Clarifying the behavior of an extreme use case and “why does this do this instead of that” might become impossible when there is only a codebase to work with.
Misconception #2: Documentation wastes time that could be spent on development instead
Why would I waste my time writing about code rather than coding at that time?
- Does writing documentation waste time in the long term?
- How can we determine whether it genuinely wastes time?
As mentioned above, as the complexity and size of the software increases, the communication overhead becomes unbearable and will inevitably result in lower throughput.
- Why?
- Because stakeholders will always have questions and they need to reach to knowledgable people to get the information.
And who knows the answer? Developers! The worst problem is that different people repeatedly ask the same questions to the same engineers.
- Do you see a task that could be automated here?
- I do; Write the docs! ☝️ #AutomateThis
Misconception #3: We don’t need to write this; it’s obvious
“We don’t need to document this. Everyone knows that!”
There is a fine line on what we need to document and what not but one thing is certain: at least some form of documentation is always needed.
Image generated by gopherkon
Some information might be obvious to you, now under your area of work. But not everything is obvious for everyone.
Documenting use cases, architecture, and interaction between components prevents misunderstandings that could result in significant errors/incidents that can be costly to businesses.
Misconception #4: No need to write this; we will remember this
“I’ll never forget this”
Famous. Last. Words.
Well, there’s not really much to comment on this one. People forget, and people leave companies. It’s inevitable. We need to accept it and be prepared for it.
- How can we be prepared?
- Write the docs! ☝️
The value of documentation
Hopefully, it’s now clear that avoiding documentation is a dangerous game to play.
Image generated by gopherkon
The value of documentation is quite evident if we think of a scenario in which we don’t have documentation:
- We need to find a person who possesses the knowledge that we seek
- Blocker: This person must be available
- Inefficiency: This person must answer the same questions over and over again to different people
- Or we will try to extract the information on our own
- If there is existing software, we can look at the code
- Inefficiency: This is a slow process
- If we seek information about things already discussed but not documented
- Blocker: Well, we can’t do anything 🤷
- If there is existing software, we can look at the code
If we want to encapsulate everything in one sentence, I would say that the value of documentation is that Documentation is always available for everyone to consume at any time.
Communication efficiency
Software documentation aims to communicate what a software system does and how it does it from different perspectives. The details can vary depending on the target audience and what documentation needs to convey.
Given this purpose, the great benefit of documentation is communication efficiency.
A software project has a lifecycle of many steps that span across different functions. It requires the collaboration of multiple roles such as Business, Product, Design, and Engineering. A contributor can wear numerous hats during a project, but communication is the key to success for teams with more than one person.
Whether we are talking about business needs, detailed use cases, edge cases, and software engineering documentation, all play a key role in communicating the purpose, the behavior of the system, and how the system is implemented.
Image by Maria Letta @free-gophers-pack
Each person involved in a software project has expertise in their function and, therefore is the single point of contact for specific areas of the project.
The presence of documentation in all areas of the project increases the efficiency by:
- Preventing consuming time from people who work on their ongoing tasks to get an answer for a question about the system’s behavior
- Someone’s unavailability does not block people. The information is documented so you can read it and proceed accordingly
- People who seek information can find what they want easily and quickly
Quick Onboarding time for new members
When a new member joins the team, we want them to be productive as soon as possible.
Depending on the existence of good documentation, the onboarding process can be either a painful resource and time-draining process or a smooth process for both the new joiner and the team.
I’ve experienced both situations, and the difference in morale and frustration and delivery times is outstanding!
This is especially important for medium-big size and high-growth organizations where hiring is constant.
Preserving knowledge
People forget, and people leave companies. And unfortunately, no one remembers everything forever, and there is no guaranteed loyalty to a company.
Concentrating knowledge on a handful of people is a horrible idea. It’s almost guaranteed to lead to an inevitably bad, bad situation.
Imagine what would happen if the people who know the business of the product inside-out left the company. It’s a massive cost for a company to take.
Thankfully it’s preventable.
- How?
- Write the docs!☝️
Promotes Alignment, Enforces Correctness
People disagree, and people forget.
Arguments and conflict resolution is part of our job. If we talk about preferences and subjective topics with competing tradeoffs, that’s expected; and inevitable.
Disagreements and arguments on already agreed product requirements, specifications, and decisions are completely preventable. This might sound obvious. But these sort of arguments is the reality of some software engineering teams.
Maintaining good documentation, especially on use cases, edge-case scenarios, and decisions made about specific parts of the project, dramatically impacts the project’s success. Here are a few examples:
- Software engineers can ensure correctness via test cases and review code against the written documentation
- New software engineers can understand the decision-making process for “Why was this done this way.”
- Product can confirm use cases and behavior and check the data points they collected to reach their decisions
Promotes External Collaboration
Lastly, good documentation, especially in large organizations and open source projects, can be used by people outside the contribution team to gain knowledge on the area of work of other teams.
Image by Maria Letta @free-gophers-pack
This greatly promotes domain knowledge and understanding and can result in cross-domain collaboration exchanging of ideas.
Common Pitfalls
As we’ve seen, the value of documentation is apparent, and software projects can benefit significantly from well-written documentation.
However, just writing any documentation is not enough. The documentation should meet a quality standard and be maintained consistently.
Below we explore some common mistakes you can see in a project where the value of documentation is well understood, but the execution fails.
The “written in stone” documentation
This is probably the most commonly found problematic state in documentation. While a team puts effort into writing documentation, there is no attention to keeping the documentation up to date.
This is a dangerous situation since it can result in the following:
- Either the documentation becomes utterly useless since it does not represent the current state of the project
- Or even worse, people could make decisions based on wrong assumptions that are presented in outdated documentation
👉 To avoid outdated information, documentation should be updated systematically as the software grows organically.
Inaccurate documentation
Often documentation is assigned and written by a team member, published in the knowledgebase tool of choice, and that’s all.
Image by Maria Letta @free-gophers-pack
Code is written and reviewed before being published. The same applies to documentation. People make mistakes, miss important information, and have misconceptions about how specific things work.
👉 To avoid inaccurate information, ensure that documentation is peer-reviewed using a feedback-provisioning process to ensure correctness.
Duplicated documentation
When there is no clear direction of what goes where and an organized way of documentation, duplication can happen.
Duplicate documentation is:
- Inconvenient at the very least. Documentation contributors have to sync the duplicate documents which is inefficient and easy to forget, and thus, error-prone
- Consumers of the information have to check multiple locations to try to identify the updated document location to extract accurate information.
- Dangerous, if consumers rely on outdated documentation
👉 To avoid duplication, provide clear rules about what is documented and where, and keep revisiting as the documentation grows.
Documentation spread in too many locations
Another relatively common problem in the software world is using too many documentation approaches and even tools/services without a clear direction of what goes where.
Image by Maria Letta @free-gophers-pack
This devalues the documentation since, if someone wants to search for something, they need to check each documentation source separately without a clear indication of what goes where.
👉 This is preventable by hosting everything together or standardizing the types of documents in each tool and how they should be structured. KISS3 usually works until a specific inefficiency is identified along the way.
Redundant, not helpful code documentation
There is a fine line between what needs to be documented and what is not.
Sometimes, the good intention of providing good documentation results in over-documentation, which is not helpful.
For example, some projects include extremely detailed documentation of what code does. However, maintaining a manual process of describing each of the classes and structs of a piece of software with helper utilities is often redundant. Providing some heads-up for important pieces of information to the developers is understandable, but extreme detail is unnecessary.
This practice can become cumbersome for developers that work on frequently changing codebases, and it also increases the maintenance effort of documentation.
👉 The line between what’s needed and what’s not is blurry. Identifying redundant documentation can be done as part of regular process evaluation/assessment. If developers recognize no or minimal value in a costly process, it could be dropped or modified to meet the team’s needs.
Essential documentation for software engineering teams
So far, we have explored some misconceptions about documentation, the value of documentation, and common problems we see with documentation.
Image by Maria Letta @free-gophers-pack
But what should we document?
We will look at this from a software engineer’s lens and share a set of documents I believe are absolutely necessary for any project.
Business Requirements and use cases
Software development is all about implementing business use cases. The first stage in the lifecycle of software development is gathering the requirements. Documenting the requirements of the system is essential, otherwise we don’t have a source of truth of what the software should do.
The next step is the technical analysis that is required to extract the specifications of the system. This is another crucial area to document as it can include the considerations and through process for final decisions on the specifications.
Based on these specifications, software engineers will implement the requested features and accurate documentation is critical.
This is the part of the documentation that team members will often visit to clarify and confirm how the system should act under specific circumstances.
Technical Documentation
The business requirements with the use cases bridge the gap between business/product and engineering.
However, the heart of a software system lies in the technical specifications and design.
Let’s see some documentation areas that provide invaluable information for engineers to understand how the system is built, organized, and operating from a technical point of view.
Organizing technical documentation
Before we explore the different technical documentation areas, defining a solid organizational structure is essential. This will promote efficient searching and maintaining documentation and avoid duplication and confusion.
Image by Maria Letta @free-gophers-pack
So, whenever I think about technical documentation, I think about it on three levels:
- System-level documentation
- Team-level documentation
- Component/Repo/Service-level documentation
System-level documentation
System-level documentation provides a high-level overview of the system.
This documentation area includes the interaction of services/components but does not include the details of how services/components are implemented.
This type of documentation should be hosted outside a repository, in a shared location, since it has a broader scope for multiple components/services.
Typical documentation sections that live in this area are:
- Tech Stack, Tooling, BoM
- Architecture Design
Tech Stack, Tooling, and Bill of Materials
One of the first things an engineer needs to know before contributing to a system is how it is built.
For this reason, engineers need to document the tech stack with the programming languages, frameworks, and managed services used by the overall system.
Architecture Design
The technical design of a system is one of the first areas in that software engineers are looking to gain a high-level understanding of the system.
System level diagram
Technical design is a very generic term. Usually, technical designs should contain the following:
- System context
- Component/Service Architecture Diagram
- Network Architecture Diagram
- Infrastructure/Deployment Architecture Diagram
- High-level Data Flow Diagram
Team-level documentation
Team-level documentation is not product-related and consists of a set of conventions, standards, and processes that a software team follows in their day-to-day work.
This type of documentation can also leave in an isolated location. However, following the “Don’t spread the documents in multiple locations”, it’s often helpful to include this type of documentation alongside system-level documentation in a separate category.
Developer’s Handbook
The Developer’s Handbook is one of the sections I have adopted in the last years and is invaluable.
All documentation that a developer should know about standards, conventions, processes, tooling, and guides that is non-feature specific lives in this space.
Let’s review some of the contents included in the dev’s handbook.
Guides
Guides can be runbooks, how-tos, and specific documented steps of achieving a goal that is commonly required and does not have a straightforward approach.
Here are a few examples:
- Release Guide
- Adding a new infrastructure as a code resource
- Deploy a hotfix
Is a recurring flow/task error-prone or not straightforward? Write a guide and share it with your team!
Onboarding
A step-by-step onboarding guide is essential for bringing a new team member up to speed without blocking other team members.
A sample onboarding document can look like this:
- Development Environment Setup
- Validate/Request Tool Access
- Review Processes
- Review Overall Architecture
- Onboarding Excercise
Processes
Every team has its practices. These practices can span at a team, domain, or company level. Therefore, documenting the processes is important to align everyone on the team.
Here are a few examples:
- Coding Standards
- Conventions
- Bug Reporting
- Addressing Technical Debt
- Development Workflow
For agile teams, this can mean sections defining:
- Definition of Ready
- Definition of Done
Component/Repo/Service-level documentation
With component/repo/service-level documentation, I refer to the documentation describing a well-defined scope/component often implemented by an isolated module or service.
Service is relevant to a service-oriented architecture, while a module can be a moderately complicated module as part of a monolithic application. This is the lowest documentation level since it contains references that you can find in the code.
Application level diagram
The information included in this documentation is only applicable and helpful for the service/component that implements the functionality.
Considering the isolated nature, it makes sense to include this kind of documentation next to the code that implements it. This way, it’s easier to maintain it along with code changes.
Here are a few sections I consider essential for this level:
- General Overview
- Use Cases implemented by the service
- High Level Structure
- Service-Level Architecture Diagram
- How to run the application
- How to contribute
- API Reference
- Troubleshooting
Conclusion
Documentation is a vast and hot topic in software engineering. Many despise documentation, and some love it.
The only sure thing, in my view, is that documentation is an investment with compound interest. With proper care and direction, documentation can be crucial to a team’s and even a company’s success.
I hope I have shed some light on the value and misconceptions of software documentation and provided some guidelines for structuring documentation in software engineering teams.
For those about to doc, I salute you 🤘
Leave a comment