---
title: "13.7 Documentation comments"
description: "Doc comments with /// and //!, Markdown in docs, building a docs website with cargo doc, and why Rust's documentation culture is one of its quiet strengths."
url: "https://learnrust.net/chapter-13/documentation-comments/"
last_updated: "2026-06-13"
---

# 13.7 Documentation comments

Lesson [1.2](https://learnrust.net/chapter-1/comments/) covered ordinary comments, the `//` notes you leave for yourself and the next reader. Rust has a second, special kind of comment that does more: **documentation comments** become a browsable website, render formatted text, and can even run as tests. They're the foundation of Rust's documentation culture, which is one of the language's understated strengths, and writing them is a habit worth forming now.

## /// documents the thing below it

A documentation comment uses three slashes, `///`, and documents the item immediately following it, a function, struct, or module:

```rust
/// Returns the larger of two numbers.
///
/// If the two are equal, returns that value.
fn max(a: i32, b: i32) -> i32 {
    if a >= b { a } else { b }
}
```

These look like ordinary comments but the compiler treats them specially: `cargo doc` collects every `///` comment and builds an HTML documentation site from them, the same kind of site you browse for the standard library. The text supports **Markdown**, so the formatting you use in these lessons (headings, `code`, lists, links) all work in doc comments and render as styled HTML.

The convention is a one-line summary first, then a blank `///` line, then any longer explanation. Tools show that first line in summary lists and the full text on the item's own page, so leading with a crisp sentence pays off.

## Documentation sections and examples

Doc comments have a few conventional Markdown headings that readers expect. The most important is `# Examples`, holding a code block that shows the item in use:

```rust
/// Adds two numbers together.
///
/// # Examples
///
/// ```
/// let sum = my_crate::add(2, 3);
/// assert_eq!(sum, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
```

Here's the part that surprises people: that example code is not just for show. `cargo test` actually *compiles and runs* the code blocks in your doc comments as tests, called **doc tests** (lesson [14.5](https://learnrust.net/chapter-14/doc-tests/) is devoted to them). If you change `add` so the example's `assert_eq!` would fail, the test suite catches it. Your documentation's examples can't drift out of sync with the code, because the moment they do, the build tells you. Other common sections include `# Panics` (when the function can panic, lesson [12.1](https://learnrust.net/chapter-12/panic-and-unrecoverable-errors/)) and `# Errors` (what a `Result`-returning function's `Err` means, lesson [12.2](https://learnrust.net/chapter-12/result/)).

> **Key insight**
>
> Doc-test examples are documentation that cannot rot. The eternal problem with example code in docs is that it goes stale: the API changes, nobody updates the example, and now the docs actively lie. Rust runs your examples as part of the test suite, so a stale example is a failing build, not a silent lie. Documentation and code stay honest with each other automatically. This is a big reason Rust libraries tend to have trustworthy docs.

## //! documents the enclosing item

There's a sibling form, `//!`, which documents the thing it's *inside* rather than the thing below it. You put it at the top of a file or module to describe that whole module or crate:

```rust
//! # My Tool
//!
//! A small library for counting words and lines.
//! Start with the [`run`] function.

/// Counts the words in a string.
pub fn run(text: &str) -> usize {
    text.split_whitespace().count()
}
```

The `//!` block at the top of `lib.rs` becomes the front page of your crate's documentation, the overview a new user reads first. Use `///` for "this item, described from outside" and `//!` for "the container I'm writing inside of, described from within." The two cover everything: per-item docs and crate/module overviews.

## Building and reading the docs

`cargo doc --open` builds your crate's documentation (and its dependencies') and opens it in a browser. What you get is the same layout as the official standard-library docs and the per-crate pages on docs.rs, because they're all generated by the same tool from the same kind of comments. That uniformity is the point: every Rust crate's documentation looks and navigates the same way, so learning to read one means you can read them all, which is exactly what the next lesson is about.

> **Best practice**
>
> Document every public item with at least a one-line `///` summary, and give non-trivial functions an `# Examples` block, both because it helps readers and because the example becomes a test. Private items need docs far less often; a plain `//` comment explaining a tricky internal is usually enough. The rule of thumb: anything `pub` is a promise to someone, so it deserves a sentence saying what the promise is.

## Quiz time

**Question #1**

What's the difference between `///` and `//!`?

<details class="solution">
<summary>Show solution</summary>

`///` documents the item that immediately follows it (a function, struct, etc.). `//!` documents the item that *encloses* it, used at the top of a file or module to describe that whole module or crate. Use `///` for per-item docs and `//!` for a crate or module overview.

</details>

**Question #2**

What happens to the code inside an `# Examples` block in a doc comment when you run `cargo test`?

<details class="solution">
<summary>Show solution</summary>

It's compiled and run as a test (a doc test). If the example fails to compile or an assertion in it fails, the test suite reports a failure. This keeps documentation examples from going stale: a broken example becomes a failing build rather than a silent lie. Lesson [14.5](https://learnrust.net/chapter-14/doc-tests/) covers doc tests in full.

</details>

**Question #3**

You're documenting a public `pub fn divide(a: i32, b: i32) -> i32` that panics when `b` is 0. What doc-comment sections would you include?

<details class="solution">
<summary>Show solution</summary>

A one-line summary first, an `# Examples` block showing a normal call (which also becomes a doc test), and a `# Panics` section noting that it panics when `b` is 0. Documenting the panic condition is part of the function's contract (lesson [12.5](https://learnrust.net/chapter-12/when-to-panic/)): callers need to know the input that will crash it.

</details>

You can now write documentation that builds into a site and tests itself. The flip side of writing docs is *reading* them, and the next lesson, the last before the chapter summary, teaches a genuinely useful skill: how to read a method signature you've never seen on docs.rs and the standard-library docs.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
