I want the code I write to be as easy to follow as possible, and proper documentation is key to accomplishing that. Documentation’s role isn’t to give a full explanation of what the code is doing. Instead, it’s a tool for setting up context. It should give other developers the confidence to move through the codebase and understand the problem being solved by the software.
I reflected on my own documentation practices and found six codebase concerns that documentation can address: who, what, when, where, why, and how. Here are a few example questions in each category and the documentation I use to answer them.
How is the codebase structured?
How do all the different pieces of the code interact?
Diagrams and flowcharts are a great way to answer these questions. They can describe high-level concepts simply and without diving into implementation details. They help a developer create a framework for the problem being solved before spelunking through the code.
What does the code do?
This is best documented by the code itself. Rather than having a block comment above particular methods, developers should focus on creating well-named functions and variables that are more likely to evolve with the software.
Instead of spending effort on continually updating documentation of an evolving codebase, the team should focus on creating an excellent developer experience directly in the code. Prioritizing refactoring and high test coverage over comprehensive descriptions in comments will accurately describe the solution the team is trying to solve.
There’s a place for documented methods in software development. For example, I’ve benefited greatly from libraries with a solidified API having extensive comments throughout the code to explain how methods are supposed to be used. However, applying this pattern to APIs going through continuous evolution becomes burdensome.
Why is a method breaking a team-established pattern?
Why did a developer decide to leave an unrefactored mess?
Every developer needs to make tradeoffs to deliver software on time. There isn’t time for perfect code in every scenario.
Leaving a comment as to why a less-than-ideal solution was implemented will help future developers. Warning of potential pitfalls will help them understand the tradeoffs you made and allow them to decide whether they should deal with the technical debt or move on.
Where should a feature begin code changes?
Leaving trailhead comments about where a developer should start writing code will help them navigate towards the right solution. On my Typescripts projects, my team identifies key areas of the code to modify that will allow a developer to follow the type system, addressing errors one at a time until the latest feature is implemented.
Adding these trailheads in stories helps ramp in developers to a new feature. You should refer to these trailhead comments when describing an implementation hypothesis for a new feature to help developers start in the right direction.
Who was the last person to edit this piece of code?
Who might know why this code is written in a particular way?
Source control naturally documents this information. However, I’ve also found some benefits to putting my initials in comments in the code. In particular, I always leave my name on a todo in case someone wants clarification.
When was something written?
When was an issue in a todo comment a problem?
Source control also naturally documents this information. Knowing when a section of code was written has marginal benefits. For example, if I see a comment that I left months ago about an issue, that issue might be gone. Someone else may have incidentally fixed the issue.
Knowing the answer to “who” and “when” provides much smaller value compared to the other concerns. However, I’ve found some marginal benefit to knowing the answer to these sorts of questions, and it requires little effort to document this information.
Any Other Questions?
Keeping a well-documented codebase is a difficult task. By asking myself these questions, I’ve been able to continue improving my documentation practices as the codebase evolves. If you have ideas on practices to keep up on documentation, please let me know in comments!