Writing and maintaining the docs¶
All documentation for the project should reside within this website to avoid searching for loose notes throughout the repo. Keep user guidance, API contracts, design decisions, and performance records in this site. When behavior changes, update the pages that explain it. AI-generated documentation is allowed as long it is concise, informative, and accurate.
Build and review¶
Run documentation commands from the directory containing pixi.toml:
pixi run --locked -e docs docs-serve
pixi run --locked -e docs docs-check
pixi run --locked docs-test # Linux
Use docs-serve to preview the site locally. docs-check audits the content
and API inventory, builds the site in strict mode, and checks local links,
anchors, assets, and the search inventory.
To verify the examples on Linux, run docs-test. It uses --Werror to compile
one driver for all maintained examples, runs it, and compares the output with
docs/examples.json. These checks are separate from the functional test
suites.
Choose the checks that cover your change. A successful site build verifies the documentation structure; example compilation and numerical correctness need their own checks. For layout or theme changes, also review desktop and mobile rendering, search, keyboard navigation, and both color themes.
The docs environment pins MkDocs and Pygments. Mojo comes from the default
environment.
Where things live¶
| Path | Purpose |
|---|---|
docs/content/ |
Handwritten pages |
docs/examples/, docs/examples.json |
Maintained programs and expected output |
docs/api.json, docs/public-exports.json |
Extracted docstrings and public symbol inventory |
mkdocs.yml |
Navigation, site configuration, and plugins |
docs/theme/, docs/hooks.py |
Rendering, assets, directives, and downloads |
scripts/docs_contract.py |
Content and API audits, directive expansion |
scripts/check_docs.py |
Rendered link and search checks |
scripts/verify_docs_examples.py |
Example compilation and output checks |
scripts/api_docs.py, scripts/api_reference.py |
Docstring extraction and API rendering |
scripts/module_layout.py, scripts/export_contract.py |
Module and export inventories |
Mathematics¶
Use LaTeX notation for equations: $x^2$ for inline math, and $$ on separate
lines for a displayed equation. Leave a blank line before and after a display
block:
$$
\frac{a}{b} + \frac{c}{d} = \frac{ad + bc}{bd}
$$
The Markdown extension preserves the notation, and MathJax renders it in the browser. Math inside code spans and fenced blocks stays literal. MathJax loads from a CDN, so rendering equations requires an internet connection.
Directives¶
Use HTML-comment directives to include API declarations and maintained examples in a page:
<!-- api: integer -->
<!-- example: docs/examples/first_integer.mojo -->
<!-- source: docs/examples/<file>.mojo -->
api inserts a package's generated declarations. example shows a program
alongside its run command and recorded output. Use source for an example
module that does not run as a standalone program. Inside a fenced block,
directives appear as literal text, as they do above.
Rules the audit enforces¶
- Every page starts with a level-one heading.
- Mojo blocks come from
exampleorsourcedirectives, not handwritten fenced Mojo code. Use atextfence for a signature or an abstract sketch. - Each public package has exactly one
apidirective. - The extracted API matches the public export inventory and has the required summaries, argument descriptions, and error documentation.
- Every runnable example is in the manifest and is referenced by a page. Recorded output ends with a newline.
The audit catches structural problems and inconsistencies. Read the prose as well, and check its factual claims against the code.
When adding a public capability, also check its route from the homepage, package index, tutorials, support guide, and example gallery. A generated declaration does not replace a runnable introduction. Keep a new example in the gallery as well as on its teaching page, and update overlapping capability and shape descriptions together.
Documenting an API¶
Edit source docstrings to change the generated API reference. Start each function docstring with a short summary, then explain its parameters, arguments, results, errors, and limits. Every overload needs a summary, and at least one declaration of each function needs complete documentation.
Use type docstrings to describe operator behavior and constructor docstrings to explain accepted inputs.
After a public API change, refresh the export inventory with
python3 scripts/export_contract.py and extract docstrings with
pixi run --locked python3 scripts/api_docs.py. Review the generated changes
and run the documentation and example checks.
Where decisions go¶
Document algorithms, proofs, and measurements that explain a design choice in the relevant architecture chapter. Benchmark results contains the generated performance summary and full report download. Explain workflows in Development or Benchmarks.
Describe the current implementation. Historical measurements are useful when they explain a design choice; include their setup so readers can judge where the results apply.
Adding an example¶
- Add a self-contained program with a
def main() raisesentry point underdocs/examples/. - Run the program and record its output in
docs/examples.json. - Add an
exampledirective and an entry in the gallery. - Run
docs-testanddocs-check.
Theme¶
The site's templates and styles live under docs/theme/. The theme uses local
assets and relative links, and supports search and both light and dark colors.
The example below uses the same directive as examples elsewhere in the site:
"""The smallest complete program: one exact Integer calculation."""
from apn_mojo import Integer
def main() raises:
var value = Integer(2) ** 100
var saved = value
value += 1
print("2 ** 100:", saved)
print("plus one:", value)
print("unchanged copy:", saved == Integer(2) ** 100)
Run from the repository root pixi run mojo run -I src docs/examples/first_integer.mojo
Output
2 ** 100: 1267650600228229401496703205376
plus one: 1267650600228229401496703205377
unchanged copy: True