Writing Maintainable Code — Using Comments to Make Code Easier to Maintain
November 27, 2025
To make a codebase easier to maintain, good documentation is helpful. For code, beyond writing separate technical design documents, comments within the code itself are a form of documentation.
Whenever the topic of writing comments in code comes up, it's common to hear people in the community say "if there are comments, it means the code isn't clear enough—you should refactor instead of adding comments."
But is that really the case?
In fact, many people who have maintained large codebases agree that code should be clear, but they also agree that comments have their place. Writing clear code and writing comments are not contradictory or mutually exclusive. When you combine well-written code with appropriate comments, they complement each other and work together to improve code maintainability.
In this article, we'll discuss in detail why comments are recommended in code, how to write them, and which comments shouldn't be written. (Yes, even though comments are recommended, that doesn't mean every comment should be added—writing them thoughtfully is what helps maintainability.)
Why Write Comments in a Codebase?
First, let's discuss why comments are recommended. In the past, many people in the community believed comments weren't necessary, based on the reasoning that "if code is clear enough, comments aren't needed." However, while code itself may clearly express what it does, it cannot explain "why" it was written that way or what context might make a particular approach more suitable. For these more meta-level considerations, comments are an excellent tool.
Going further, good software design should hide complexity. To hide complexity, we need abstraction (see Writing Maintainable Code — What to Watch Out for When Using Abstraction), so that other developers using that code don't need to worry about the details underneath. Therefore, if a developer needs to read the implementation details to understand how to use a function or method, the purpose of abstraction is lost.
For example, if a function has start and end parameters, looking at just the parameter names doesn't tell you whether these values are inclusive (for instance, if end is 10, does that mean up to 10 or including 10?), nor does it explain how the code handles the case where start > end.
With comments, developers can know these critical details without reading the function's implementation, which achieves the purpose of abstraction. Therefore, regardless of how clear the code itself is, good abstraction combined with good comments will benefit the entire codebase's maintenance.
Lack of Time is No Longer an Excuse
Another common reason for not writing comments is "lack of time." During development, many developers consider comments a lower priority, so they prefer spending time writing new features rather than documenting already-completed ones. This is understandable.
However, in software development, there are always more features to write. If developers skip comments because of new features, there will never be comments. From a long-term perspective, the cost is reduced maintainability. From a cost-benefit angle, the time spent writing comments is far less than the time other developers spend trying to understand uncommented code.
Moreover, with AI assistance, the time cost of writing comments has dropped significantly compared to the past. You can now directly use tools like Cursor or Claude Code to write code with comments simultaneously, or add a /add_comment command to have AI write comments with one click—developers only need to review them.
Therefore, if your team has historically skipped comments due to time constraints, consider adopting AI tools and letting team members know that writing comments has a high return on investment for long-term codebase health.
What Should Be Written as Comments? What Types of Comments Are Recommended?
After understanding why comments matter, let's discuss what should be written as comments.
As already mentioned, the greatest benefit of comments is capturing information that code cannot convey, allowing future developers maintaining the code to get up to speed more quickly. Especially for new team members, comments in code can significantly reduce cognitive load and uncertainty.
Without recording this context and reasoning, future developers won't know why the code was written that way, leaving them to guess the original author's intent. This takes more time and may lead to errors in maintenance due to misunderstanding the original intent. Often, the person maintaining the code in the future is yourself—many people forget why they wrote something just months later. Comments aren't only for helping other developers; they often help your future self.
By recording the most important "why" through comments, this becomes invaluable for future maintainers. From our practical experience, we once saw code that seemed oddly written, as it didn't follow the framework's recommended approach. Fortunately, that code had comments explaining the reasoning. When reading those comments, we discovered the original reason no longer applied, so we confidently refactored without being stuck wondering "why was this written this way? What might I miss if I refactor?"
Recommended Types of Comments
Previously, Redis author antirez wrote an article called Writing system software: code comments. analyzing comment types he considered worth writing. Several of these are particularly worth recommending.
The first type is interface comments. Antirez calls these function comments, but looking closely at the definition, this type applies to any interface, not just functions. Interface comments allow maintainers to understand what a module does by looking only at the interface, without needing to examine implementation details. This is a comment type that should definitely be written in a codebase.
For example, even ignoring the implementation details, you can completely understand what this function does:
/* Find the greatest key in the subtree of the current node. Returns 0 if
* there is not enough memory, otherwise 1. This is a helper function used
* by different iteration functions below. */
int raxSeekGreatest(raxIterator *it) {
// implementation details omitted...
}
The second type is design comments and why comments. Both types focus on explaining why a piece of code was designed a certain way. These comments help future maintainers understand why a particular approach—which might not be immediately obvious—was chosen. This is very helpful for maintenance.
The third type is teaching comments (antirez's article uses both "teacher comment" and "guide comment" for similar purposes). These comments aim to explain information that might not help people familiar with the codebase but would be very useful for newcomers to the team. Unlike the previous type, which explains non-obvious reasoning, these lean toward teaching how the code works.
Antirez's article covers more categories of comments, but from our practical experience, the three main types above are the most worthwhile to write from a maintainability perspective.
Read More
For more information on how to write good comments, what should and shouldn't be commented on, and what to watch out for when writing comments, we have detailed discussions in our E+ topic articles. Our Writing Maintainable Code series and courses also cover other points that help with writing good code. We welcome you to join E+ to view them (link)