shutterstock

How to Write Code Documentation: Examples, Types, Best Practices, and Tools

Every developer has been there—staring at a codebase they wrote months ago, struggling to remember the reasoning behind certain decisions or how different components fit together. Few things are worse than looking at your own code later and not remembering what it does or how it works.

Another common occurrence is when a new teammate gets onboarded into a project and can’t understand the code because the previous developer felt it would be obvious enough.

These scenarios are all too familiar and highlight a crucial part of programming that often gets overlooked: code documentation. It’s not enough to write the most beautiful code ever. You should also explain it.

In this article, we will explore the importance of code documentation, its types, best practices to follow, code documentation tools, and more. Let’s dive in.

What is code documentation?

Code documentation is the process of creating descriptions and comments that explain how a piece of code works, what it does, and how to use it.

 These explanations bridge the gap between the code itself and the humans who interact with it. Stakeholders who use code documentation include:

  • software developers—for example, your future self and colleagues collaborating on the same codebase, future maintainers of the code, and new team members;
  • project managers who need to understand a project structure, determine its progress, assess technical debt, and plan future development;
  • members of a quality assurance team using code documentation to learn about the expected behavior of the software product and test both typical scenarios and edge cases; and
  • technical writers leveraging code documentation to create user manuals and other types of technical documentation.

Code documentation provides several benefits, including clarity, easier maintainability, better collaboration among team members, and improved developer onboarding for new hires joining a project.

Code documentation vs documentation as code

While they sound similar, code documentation is not the same thing as documentation as code (docs-as-code). Code documentation is the practice of writing explanations directly within the code or in a separate file to help developers understand how it works and how to use it.

On the other hand, docs-as-code is an approach that involves creating and managing ocumentation with the same tools and processes you use to write code. This includes:

  • version control systems to house source files, track changes, and store different variations of documents;
  • automated testing tools to find spelling and syntax errors, broken links, style violations, etc.;
  • CI/CD tools to generate, update, and deploy documentation.

Docs-as-code ensures that all types of software are always up-to-date, versioned, and maintained alongside the project it describes. The approach covers code documentation but is not limited to it.

Code documentation types

Code documentation can be internal  — meaning that it’s located within the codebase itself, or external, in the form of separate files. The former type, also called source code documentation,  falls into two major groups  

  • code comments, and
  • documentation comments or strings (like docstring in Python) that can be parsed by documentation generators and converted into documents in HTML, PDF, or other formats.

They can be single-line or multiline, the latter used for providing additional context or explaining complex sections. Single-line comments typically can be no longer than 80 characters.

Both groups improve code readability, clarity, and maintainability but serve different purposes. Each programming language has its own syntax for comments and documentation strings.

Comment syntaxes across different programming languages

Comment syntaxes across different programming languages

External code documentation is usually README files describing how to implement, run, and configure your code and its expected outputs.

API documentation is sometimes also referred to as code documentation. Our separate article, How to Write API Documentation, explains more about it. In this post, we’ll focus on other varieties of code descriptions.

Code comments

Code comments, also called inline comments, are brief notes that describe what a line or block of code means or does. They live exclusively in source code files and are invisible to compilers and browsers. The image below shows comment examples for a piece of JavaScript code.

JavaScript code with inline comments added.
JavaScript code with inline comments added

When to use them

Code comments are useful for explaining non-obvious things—such as

  • the high-level purpose of a code block,
  • novelty or complex algorithms,
  • why a particular (probably non-ideal) solution was chosen, and other implementation decisions; and
  • TODO and FIXME notes to remind of what must be changed or improved.

You can also use comment syntax to temporarily disable code sections during debugging or development for quick testing and iteration (since, as you remember, the compile doesn’t see lines marked as comments.)

Multi-line code comments explaining the implementation decisions behind a piece of JavaScript code

Multi-line code comments explaining the implementation decisions behind a piece of JavaScript code

How to write code comments

Let’s discuss some best practices for writing clear and helpful comments in your code.

Write self-documenting code. The best code is self-documenting  — meaning, it’s so clear and expressive that little to no comments are required for additional explanation. The image below is an example of code that can be hard to understand.

An example of hard-to-understand Python code

An example of hard-to-understand Python code

The image below is an example of self-documenting code: The function and variable names clearly convey their meaning and purposes.

An example of clean Python code.
An example of self-documenting Python code

Ensure your comments are clear and easy to understand. Write comments that are concise, clear, and easy to understand. Avoid jargon unless it's necessary and well-known in your field. The image below is an example of a vague and unhelpful code comment.

Unclear comments added to JavaScript code.
Unclear comments added to JavaScript code

The image below is an example of detailed comments: They explain what the code does and even provide the formula being used.

Clear comments added to JavaScript code.
Clear comments added to JavaScript code

Explain why. While it's important to document what your code does and how it does it, explaining why certain decisions were made can provide valuable context for future developers (including your future self). Give the reasoning behind architectural choices, algorithm selections, and even specific lines of code that might not be immediately obvious.

The comment in the image below does not explain “why” the quicksort algorithm was used. It only states what the code does, which is already evident.

Comments in Python code do not properly explain why coding decisions were made.
Comment in Python code does not explain why coding decisions were made

In contrast, comments in the next image properly explain why the developer chose the quicksort algorithm.

Comments in Python code properly explain why coding decisions were made.
Comments in Python code explain why coding decisions were made

Link to the original source of external code. It's important to provide links when adding code from external sources to your project. This practice gives credit to the original author and helps others understand the context and find additional information if needed. Including the source link ensures transparency and helps maintain your codebase's integrity.

Code comments showing the source of copied Python code
Code comments showing the source for copied Python code

Docstrings or documentation comments

Documentation comments (docstrings in Python, javadoc comments in Java, etc.) give a brief summary of classes, functions, methods, and packages. Ideally, they should enable readers to grasp what a particular block of code does.

Similar to code comments, docstrings help keep the code readable. But while the former primarily targets developers who will maintain and modify the program, the latter's intended audience is engineers who will use the project and, thus, need to know how its different elements work. Most probably, they will interact not with the source code but with API or other documentation generated from docstrings.

When to use and how to write documentation comments

Documentation comments should accompany every single module, function, class, and method that is part of a public API. This type of annotation must

  • start with a brief description of the object's purpose  — it should be a one-line sentence following the “do this” structure;
  • provide detailed information on the code part; and
  • mention any exceptions and restrictions associated with the fragment. 

For example, when defining a function, a doc comment should detail its parameters, input and return values, when it can be called, etc. The image below shows a docstring for a square function in Python.

Docstrings added to Python code.
Docstrings added to a square function in Python

For a class, it’s essential to cover its purpose, behavior, attributes, and methods.  Each method, in turn, needs a documentation comment about its usage, arguments, and side effects. Adding notes on exceptions informs other developers about possible error scenarios and how to handle them appropriately.

JavaScript function with a note that mentions an exception
JavaScript divide function with a note that mentions an exception

Documentation generators

Each language has its specific tools to automatically create API documentation in HTML, PDF, or other formats from documentation comments:

  • pydoc, pdoc, or Sphinx for Python;
  • javadoc by Oracle for Java. IDEs like NetBeans, Eclipse, and IntelliJIDEA have embedded support for javadoc;
  •  DocFX for C# and other .NET projects. and
  • JSDoc for JavaScript.

Though primarily working with Python, Sphinx also supports C++, JavaScript, and other languages. Alternatively, you can use Doxygen, an open-source platform-agnostic doc generator compatible with C, C#, C++, Java, Python, and PHP.  Note that doc generators are limited to annotations they come across in the source code  — they’re not capable of adding any context or other useful information beyond comments.  

Code documentation tools

Today, different tools help developers write both code and documentation comments. You can access such assistants right in the integrated development environments (IDEs) or code editors, or easily add them as extensions. Though digital assistants can’t do all the code documentation work for you, they are great time savers.

Сode editor extensions

Many IDEs and code editors come with embedded tools, plug-ins, and extensions to improve and simplify code documentation. For example, if you use Visual Studio Code (VSCode), one of the most popular code editors, you can take advantage of extensions like Better Comments or autoDocstring.

Better Comments categorizes annotations in alerts, TODOs, and other groups to make them more user-friendly. The tool supports nearly 80 programming languages.

Comments added to a code snippet with the Better Comments VSCode extension.
Comments added to a code snippet with the Better Comments VSCode extension

autoDocstring automatically generates documentation comments in Python offering various docstring styles, including Google’s and Numpy’s, and allowing you to customize the docstring format.

Docstrings generated with the autoDocstring VSCode extension.
Docstrings generated with the autoDocstring VSCode extension

Generative AI to automate code documentation

Generative AI tools are becoming part of developer's daily routine. Powered by large language models, they can assist you with explaining and documenting code. Of course, comments and descriptions produced by AI should be manually checked for accuracy and completeness.

GitHub Copilot, primarily known for its AI coding capabilities, also generates inline comments explaining behavior and purposes of a selected code fragment. It works as an extension of VS Code,  Visual Studio, Neovim, the JetBrains suite of IDEs, and Azure Data Studio.

code documentation with GitHub Copilot
Code documentation with GitHub Copilot

JetBrains AI Assistant is an in-IDE tool driven by OpenAI models and available in all JetBrains development environments such as IntelliJ IDEA for Java and Cotlin, PyCharm for Python and data science, ReSharper for .Net, and others. In addition to code competition and refactoring, the assistant has a “Write Documentation” feature to analyze a selected class, function, or other code section and generate comments for it.

Mintlify Doc Writer is an AI-powered documentation writer that supports 10+ languages and 9 formats. All you need to document a piece of code is to highlight a line or block and click the “generate docs” button. Mintlify Doc Writer is only available as a VSCode or IntelliJ extension.

Comments auto-generated by the Mintlify Doc Writer VSCode extension.
Comments auto-generated by the Mintlify Doc Writer VSCode extension

ChatGPT is a versatile tool that can be applied to various use cases, including documenting code. You can use prompts like “generate comments for the following code snippet” or more  detailed commands  — such as “add comments to explain the logic behind the algorithm” or “add comments that describe input parameters and expected values of the function.”

To document code with ChatGPT, you can either insert the part you want to describe into the ChatGPT interface or access AI right from your development environment if a corresponding plugin is available. Examples of ChatGPT extensions are AssistAI for Eclipse IDE, EasyCode ChatGPT for JetBrains IDEs, the ChatGPT extension for VS code, and more.

Comments added to JavaScript code with ChatGPT.
Comments added to JavaScript code with ChatGPT prompt “Generate comments for the following code snippet”

Unlike all the tools mentioned above, ChatGPT can be helpful for generating the README files we’ll discuss in the next section.

README files

A README file is a document that introduces users to your software product. Typically located in the root directory of the project, it’s the first software description people see when visiting your repository.

README file for React open-source GitHub repository.
README file for React open-source GitHub repository

Every software project, regardless of its size or complexity, should have a README file.

But it’s especially important for open-source projects. The document provides potential contributors with information on the project's purpose and how to get started with it along with guidelines for contribution. A well-crafted README can be the difference between a thriving community-driven project and one that struggles to gain adoption.

README files structure

README files are typically written using markdown—a lightweight markup language to format the style and structure of plain text. The document should contain the following sections:

  • Title  — a name and a brief explanation of what the project is about.
  • Description  —  a summary of what the project does, its purpose, and its key features.
  • Table of contents  — a list of the sections in the README, linked to their respective headers.
  • Installation instructions containing any prerequisites, dependencies, commands, and configurations needed.
  • Usage instructions, including code examples, CLI commands, or screenshots to illustrate its functionality.
  • Features to help readers understand the project's capabilities.
  • Contribution guidelines informing on how others can contribute to the project. This includes guidelines for submitting issues, feature requests, and pull requests.
  • License info, which is crucial for open-source projects.
  • Acknowledgments, covering credits to any third-party libraries, tools, or resources used in your project.
  • Project status  — Information about the project's current status (e.g., in development, stable, deprecated) if relevant.

The exact structure of a README file largely depends on the nature of your project and whether it is for internal use or open-sourced. For example, an internal project may not need sections for contribution and contact information.

How to create READMEs

As we mentioned above, you can leverage ChatGPT to help you with generating README files. Their quality will depend on prompts you’ll create to make AI understand what you want from it. Read our article on prompt engineering to understand how to talk to AI effectively. Yet, there are also a range of other, simpler tools that can save you time when working on READMEs.  

Markdown editors are essential for writing and formatting README files. They have  easy-to-use interfaces and offer features like live previews, syntax highlighting, table of contents generation, exporting to HTML, PDF, and other formats, and more. Great markdown editors worth considering include Typora, Dillinger, and Obsidian.

README generators automate the creation of these files, providing templates and guided steps. They ensure that a document contains all the necessary sections and follow best practices. One of the most widely used README generators is readme.so, an open-source tool that offers an interactive web-based editor, pre-built sections and templates, live previews, and drag-and-drop section reordering.

Code hosting platforms are primarily used for collaboration, version control, and storing code in repositories. However, they also support markdown, making them suitable for creating and managing README files directly within the repository. For example, GitHub provides a web interface for editing and previewing README files directly in the repository. Also, since it supports version control, you can use it to track changes made to the README file and who made those changes.

Best practices and examples for code documentation

Here are some tips and best practices you can follow to create high-quality code documentation.

Understand your audience

Before writing code documentation, it's crucial to understand who will be reading it. Consider your audience’s technical proficiency and familiarity with the codebase. This will determine the level of detail required for the documentation.

For example, a beginner developer will require more details and simpler terminology than an expert with decades of experience. The image below shows code documentation fit for an expert JavaScript developer.

Code documentation for an audience of expert JavaScript developers.
Code documentation for an audience of expert JavaScript developers

The image below shows code documentation fit for a beginner JavaScript developer. While it is longer, it will be easier for this audience to understand.

Code documentation for an audience of beginner JavaScript developers.
Code documentation for an audience of beginner JavaScript developers

Document as you write the code

Integrate documentation into your coding process, which can mean:

  • writing function docstrings before or while implementing the function;
  • adding inline comments as you write complex logic; and
  • updating the README file with new features as you implement them.

Writing documentation as you code ensures that it accurately reflects your thought process and implementation details.

Include prerequisite information

Document any prerequisites or assumptions your code makes. This helps other developers understand what they need before they can use your code effectively.

For example, the prerequisites for the project in the image below are Python version 3.7 or higher, Numpy version 1.18 or higher, and OpenCV version 4.2 or higher. The developer in charge of the code also assumes that input images are in RGB format and have been preprocessed to remove any artifacts or noise.

Python code includes details of prerequisite information

Python code include details of prerequisite information.

Python code documentation that include details of prerequisite information

Use a consistent documentation style

Consistency in formatting and style is key to creating professional code documentation.

You can achieve uniform code documentation by creating a style guide for various elements like terminology, tone, structure,  indentation, line breaks, spacing, and docstring formats.

Avoid overdocumentation

While comprehensive and thorough documentation is necessary, it's equally important to avoid too many comments. Overdocumentation occurs when you provide excessive, unnecessary, or redundant information that can clutter your code and make it harder to read.

An example of overdocumenting code and adding unneeded comments is explaining what an array or variable is, as most developers are familiar with these concepts. The image below shows overdocumented code.

An overdocumented JavaScript code.
An overdocumented JavaScript code

The image below shows a concise code documentation that contains only the relevant information.

Concise JavaScript code documentation.
Concise JavaScript code documentation

Review and update the documentation regularly

Documentation should evolve along with your code. Regularly review and update your documentation to ensure it remains accurate and relevant. You can keep documentation updated by:

  • including documentation review in your code review process;
  • setting up reminders to periodically review project-wide documentation; and
  • encouraging team members to flag outdated or unclear documentation

Following the highlighted best practices will allow you to create effective code documentation that makes your code easier to maintain in the future and improves collaboration with other developers.

Also, remember that good documentation is an ongoing process that evolves with your code. Make it a habit to document as you code; your future self and team members will thank you for it!

Comments