Documentation is broken | LeadDev
Engineers encounter new code all the time – when starting a new job, shifting between projects, and with almost every code review. Getting into new code is a challenging task. Yet, developers often face new code without aid – causing frustration and roadblocks in the development flow.
One possible solution would be internal code documentation, but the way engineering teams approach documentation today is broken. If documentation does exist, it is almost always outdated and never found when needed.
I’d like to propose a new way of thinking about documentation, one where it’s continuous and code-coupled. Developers deserve practical documentation that is easy to maintain and easy to find. And as an engineering leader, it’s up to you to promote the best practices that enable the transfer of code knowledge in an efficient and effective way.
When do developers need to understand code?
Developers onboard into new code all the time. One obvious example is onboarding at a new job; therefore, the entire codebase is new to them. However, developers are actually encountering new code every day – when performing a code review, debugging, or when implementing a feature, they need to understand how to interact with software other team members have created.
New code is written all the time, and let’s be honest, it accumulates fast. This creates knowledge silos, as not all developers are acquainted with the code in your codebase. Even if a developer reads and understands the written code, they are not necessarily aware of all the underlying reasons why it has been implemented in a certain way, or the subtle best practices that have to be kept when making changes to it.
As a result, you’re often limited when assigning tasks to engineers. You may have a task that needs to be done, but only one person is familiar with all the relevant code. If they’re not available, this task simply cannot be completed. Even if that person is available, they’re often also someone that is knowledgeable regarding other important parts of the codebase.
In an ideal world, developers would be able to start working with new code with ease. Of course, if an engineer has worked on a specific part of the codebase, they will be the one who knows it best, but everyone on your team should be able to contribute to code with moderate effort.
How can you facilitate knowledge sharing effectively?
Existing approaches
Clean code
One approach is generally referred to as “clean code” or “self-explanatory code.” When code is well written, it’s easier to understand it in isolation.
However, even clean code doesn’t tell the whole story. Design decisions, business logic, or the underlying reasons behind not implementing something in a certain way don’t just appear in the code, no matter how clean it is.
Developers today are faced with trying to understand the complete picture of the code. Not just a specific line or function but the links between them.
As projects become more complex, spanning multiple microservices and repositories, perhaps they’re even implemented in different programming languages. If you have a clean function performing a REST API request to a remote service, it doesn’t tell you where the repo of the code that receives this request resides.
Lectures
Another approach is to host lectures, where the developer who has written most of the code in a certain part explains the logic behind it. While lectures are a great way to provide a high-level picture, they have a few major limitations. Most importantly, they are not very accessible. When a developer needs a piece of information, even if the information was delivered in a lecture, it’s really hard (if not impossible) to find that information when needed.
When lectures are given without a record, no clear reference remains, and they take a lot of time, especially as they need to be repeated. If they are recorded, they are liable to become outdated soon enough unless they describe only the high-level picture. As a result, lectures usually describe the system’s architecture and main components, but they don’t get into the details, which means their impact is limited.
Another way of transferring knowledge between the person who originally implemented the code and developers who will need to understand it in the future is to write documentation.
In order to explain concepts that span across different files, modules, and repositories, documentation should not be limited to comments within the code. A good walkthrough document takes readers on a guided tour of the code. This kind of document provides an experience similar to being familiarized with a codebase with the help of an experienced contributor.
But documentation, in its current state, is fundamentally broken. Documents become outdated as code evolves. This is not just a theoretical problem – as source code changes all the time, documents become out of date just as frequently. This creates a vicious cycle. Developers lose faith in the value of documentation as they stumble upon outdated documents. Even worse, upon finding a document, the developers simply can’t tell if it’s up to date or not, so they need to validate every piece of information to rely on it.
If writing a document will inevitably result in an outdated document in the near future, why even take the time to write it in the first place? One possible workaround is to write only very high-level documentation describing things that you know won’t change frequently. Unfortunately, this solution leaves a huge gap and neglects the crucial details to enable engineers to understand the code.
Furthermore, even the best documentation in the world won’t help if you can’t find it when you need it or don’t know if it even exists. If you do take the time to switch contexts from your IDE to an internal knowledge base or wiki, you may not find the document you are looking for, especially since knowledge about code tends to be scattered over many different platforms. Again, why bother writing a useful document if the developers who need it won’t find it when they need it most?
A new solution: Continuous Documentation
There must be a better way. Here at Swimm, we built a knowledge management tool for code. We allow engineering teams and leaders to share knowledge about their codebase so that the documentation is kept up to date and that engineers find it when they need it. As an engineering leader, this would allow you to break down barriers and empower every developer on your team to understand and contribute to any codebase or project faster and more efficiently than before.
Developers create walkthrough documents – engaging cross-repository docs with content components (such as variables, tokens, file/folder paths, code snippets, and diagrams) that interact directly with the code and are automatically synchronized as changes are made.
Documentation is kept up to date using AI, which makes recommendations as part of CI/CD workflow. On every PR, the algorithms indicate when everything is okay or alert you when something needs reviewing, suggest corrections to approve, and can even automatically correct simple issues for you. This way, the documentation is always up to date, and developers can trust it.
While working within your IDE and reading through code, Swimm’s plugin shows a comment from a relevant document that may be helpful for this part of the code. By clicking the comment, the document opens right from the IDE.
We want to break the vicious cycle of documentation. Documents are kept up to date with as little effort as possible and can be found without even needing to search.
Wrapping up
Developers deserve practical documentation that allows them to quickly understand code they’re unfamiliar with, and then contribute to it. As a leader, it’s your job to ensure that your team has the tools and information needed to succeed.