Tech Writing

The Holy Grail of “Always-Up-to-Date” Documentation

When you ask someone what’s wrong with your documentation, the top 3 answers will be: no one reads it, it is misleading, and it is outdated. In this post, we will discuss how to keep your documentation up to date.

Hey, doc! Why so outdated?

Documentation is not source code. For code, you can write tests and check whether it works before the release, but for content-related things, such checks are harder to implement. So the question is this: how can we make sure documentation is up to date and working properly? But before we answer that, let’s take a step back and try to understand why it becomes outdated in the first place. Usually you can blame at least one of these two factors:

  1. The docs are too detailed. There is no need to document each line of code if doing so doesn’t solve the readers’ problems. At the same time, it is not easy to find a balance between too little documentation and too much. So the trickiest part of the process is to choose the appropriate level of detail and stick to it throughout the document.

    Avoid going too deep into the details, since keeping your docs up to date will become a ball and chain as they grow in size. Get rid of the details that do not add any value. For example, stay on the level of modules or classes rather than functions and variables. Unfortunately, there is no silver bullet here – you just need to make a decision and stick to it. 

  2. Documentation describes an interface instead of user scenarios and the logic behind a solution. This is also called descriptive writing. When this approach is taken, the author describes each window, button, and switcher, even the obvious ones. As a result, documentation gets overloaded with details and becomes outdated quickly as the UI changes. Another approach is action-based writing, where you focus on user scenarios and help solve problems. In this case, you explain the overall logic of the solution and guide the user through some tasks, so a minor change like a new icon won’t be a blocker.

Seeking the golden mean

The methodical effort needed to keep docs up to date does not match the “move fast and break things” approach that is common among software companies. This is why “fast-and-furious” companies often take a reactive, post-processing approach to their docs.

However documentation and code serve different business goals. Code provides customers with the solution they need, but without documentation, code is not a full-fledged product. 

Documentation is a powerful tool that

  • Builds trust in your product,
  • Boosts customer satisfaction,
  • Gives business a competitive advantage.

For example, according to this recent Octoverse report by GitHub, developers see a productivity boost of about 50% with easy-to-source documentation.

When JetBrains recently unveiled the preview for a new IDE, the HackerNews community identified documentation as a competitive advantage:

“In my experience, VSCode is not competitive with JetBrains products. Their products come with support and good documentation”.

The question is not whether to document software, but how to incorporate documentation into a company’s processes without making it an obstacle or an obligation, since this is what best ensures that it stays up to date.

How do we do it at JetBrains? Here are a few tricks.

Work closely with the product and development teams

At JetBrains, we have a working culture of “not me is not an option”, meaning that everyone involved in a process is responsible for its end result. Yes, a technical writer may receive tasks from the product team or the development team. At the same time, writers actively follow product plans and updates and set tasks for themselves because they see a need they can fulfill.

As a writer, you must become a real, proactive member of the development team, not just a silent observer. There are many channels where you can learn about updates. You can, of course, ask developers to notify you every time they need a doc update, but nothing beats direct communication with the engineering team. If you participate in demos, daily meetings, planning sessions, and group chats, you will know what’s going on with the product. 

This approach has one more benefit – technical writers become more integrated into the development process. The developers know that you exist and will ask for your advice and help earlier in the process. It’s a true win-win when this happens.

Store docs closer to the code

Keep documentation in the code repository so developers know where it is. They even can help with updates, at least with a draft version. This also means you’ll have the docs under version control with a record of who changed what.

When we write code and docs in different tools and keep them in different version control systems, we implicitly keep them separated. Keeping the documentation and code together allows us to control changes more easily. There is room for discussion, though. Is it better to place doc files near related source code files or in a separate /docs directory? We use both approaches, depending on the project. 

One last benefit: You can automatically check whether you need to update the docs. For example, you can add a stage to your CI/CD pipeline that raises a warning if the code was updated but the documentation was not.

Get notified about changes

You can automate notifications with a task tracker, setting up a workflow that creates tickets in your task tracker automatically along with the development tickets – for example, when a ticket’s status changes or when it gets a specific tag.

In our team, we set up notifications for UI string changes. All UI strings are kept in property bundles. When a commit affects a resource file, Space automatically creates a review, assigns it to the responsible writers, and notifies them via email. A technical writer reviews changes and accepts them or offers suggestions to the developer about what to adjust. Once the review is finished, Space pushes all changes to Crowdin for translation. Thus we kill three birds with one stone:

  • Review UI texts in the product.
  • Receive notifications about changes.
  • Deliver only grammatically correct and verified strings for localization.

The other side of the coin is that sometimes the implementation or even the development direction of products change, which can result in duplicate work or long-running tickets. Bear this in mind as a possible tradeoff.

Another option is to set up notifications about code changes in Slack (or another corporate messenger). In JetBrains Space you can set up integration with Slack using webhooks to send such notifications. The same is true for GitHub, GitLab and Bitbucket.

The main point is to choose what triggers notifications. Some options to consider are:

  • Any changes in the code
  • Only major changes (new classes, models, or views, for example)
  • New pull requests
  • Data structure changes

Based on our business needs, we decided to go with notifications for UI string changes and significant code updates. Choose what’s best for you.

Schedule updates

You can store the timestamp for each document and create a schedule for regular maintenance. For example, employees at gov.uk set a “review by” date for each page and set up a bot that sends an automatic reminder to perform reviews.

Read more about Daniel the Manual Spaniel

They called it Daniel the Manual Spaniel and even made it open-source so you can adapt it to your workflow.

Of course this approach is time consuming if you have a lot of documentation and barely enough time to prepare it, let alone enough time for regular reviews. Nevertheless, you can give it a try, at least for popular or critical pages of your documentation. See which pages get the most views according to an analytic tool or most responses via a feedback widget. 

You can also experiment with using different review periods for different articles depending on your workload.

We’ve decided to make Monday a dedicated day for updates and content rework and set the reminder for ourselves. We will let you know how it worked for us in later posts.

Automate wisely

Docs usually consist of free-form prose that explains concepts and approaches, in addition to non-free-form material that can be automated. 

Use automation where appropriate: 

  • Do not hardcode shortcuts — we reference them from the special artifact that in turn extracts them from the product source code. 
  • Extract icons and UI strings from source as well — we reference them using an ID or a property key.
  • Auto-generate the reference sections, like we do for the list of inspections – colleagues from Kotlin auto-generate all of their code documentation with a tool called Dokka.
  • Reference code stored in a repository as code samples – we indicate a range or lines or an entire file. This prevents samples from becoming outdated. 

You can do more than just reference code samples from the repository. In fact, you can even make unit tests for each one. If the test fails, it means that something has changed in the behavior, and you need to update not only a code sample but the doc itself.

Screenshot updates are another automation feature that would make any technical writer jump with joy. 

Our team has been experimenting with a tool that generates multiple variants of each screenshot depending on the user’s environment, language, and theme. The idea is still kind of up in the air, but the trick is not to overcomplicate the documentation process. Can we come up with a tool that solves this problem? Stay tuned.

The major downside of automation is obvious: You don’t have control over changes, and if something breaks, you might not even know that you have a bug in your docs. So always bear in mind that there are both benefits and risks. We’ve only had to deal with a couple of curveballs of this sort, which isn’t so bad overall.

Will new tooling help?

The idea of documentation coupled with code lays the foundation for new tools and startups. Take Swimm, Nots.io or HastyDocs, for instance. All of these tools link code with documentation through the use of certain tags or comments. Then the tool incorporated into your delivery pipeline follows changes in code and flags docs as outdated.

Keeping docs up to date is a meta-task that requires soft skills as much as automation and tooling. Combine active team communication with code/docs transparency, set up change notifications, use automation wherever possible in the code samples, and maybe (just maybe!) you won’t miss that update again. 

This post cannot describe a complete solution to the problem of keeping documentation up to date. We’ll be happy to learn from you and your experience. What works for you and what doesn’t? What new tooling are we missing out on?

Share in the comments, let’s talk.

image description