Skip to main content

Assets guide

A curriculum this size will accumulate hundreds of images. Without a budget and a layout convention, the repository becomes slow to clone and impossible to audit. Both are enforced by pnpm content:assets.

Where files go

static/img/<module-directory>/<document-slug>/<name>.<ext>

The path mirrors the document that owns the asset, so deleting a lesson makes its orphaned assets obvious — and the orphan check fails the build until they are removed.

Genuinely shared diagrams live in static/assets/diagrams/. Downloadable files — sample repositories, cheat sheet PDFs — live in static/assets/downloads/.

Referencing an asset

Docusaurus serves static/ at the site root, and the site is deployed under a base path. Always use a root-relative path; never ../../static/...:

![The interactive rebase todo list, showing three pick lines](/img/05-history-and-rewriting/interactive-rebase/todo-list.png)

For a decorative image, or a diagram with a transparent background that should not get a border, append #plain:

![](/img/01-foundations/object-model/arrow.svg#plain)

Formats

ContentFormatWhy
Diagrams, graphs, flowchartsMermaid or <GitGraph>Text, diffable, themable, accessible — always the first choice
Diagrams that must be hand-drawnSVGScales, small, editable in a text editor
Screenshots of a GUIWebP, PNG fallbackLossless where it matters, small
PhotographsWebPNothing in this curriculum should need one
AnimationsNot permittedUse a <Terminal> sequence or a lab instead

Prefer generated diagrams over drawn ones. A Mermaid diagram is reviewable in a pull request; a PNG is not. Reach for an image file only when the diagram genuinely cannot be expressed as text.

Size budget

LimitValueEnforcement
Single file400 KBError
Per-module total20 MBError
Screenshot width1600 px maximumConvention

Before committing a raster image:

# Lossless PNG optimisation
oxipng -o 4 --strip safe image.png

# Or convert to WebP, which is usually 30–50% smaller
cwebp -q 82 image.png -o image.webp

For high-density displays, supply a @2x variant beside the original and let the browser choose. @2x is the only filename suffix permitted.

Naming

Lower-case kebab-case, describing the content, not the circumstances of capture:

GoodBad
todo-list-editor.pngScreenshot 2026-07-22 at 14.32.11.png
three-way-merge.svgdiagram2-final-v3.svg
conflict-markers@2x.pngconflict_markers_2x.PNG

Alt text

Every image needs alt text, and it is checked.

  • Describe what the image shows, not what it is. "Diagram of the merge" is not alt text; "Two branches converging on a merge commit whose parents are the tips of each branch" is.
  • Screenshots: describe the state being demonstrated, not the chrome. Nobody needs to know it was a macOS window.
  • Decorative images take alt="" and #plain. An image with no informational content and no empty alt is an accessibility defect.

Licensing

Only commit assets you created, or that are licensed compatibly with CC BY-SA 4.0. Third-party assets require an attribution line in static/assets/ATTRIBUTION.md recording the source, the author and the licence.

Never commit a screenshot containing a real person's name, a private repository URL, an email address or a token. Use example.com, octocat and obviously fictional data.