Skip to content
Connect an agent
Get started

Diagrams in Markdown and on GitHub

How a diagram fence in a Markdown file becomes a picture that GitHub displays, and how to keep it current. It is for anyone adding diagrams to a README or a doc.

For
  • GitHub
  • GitLab

TL;DR

RuleYesNo
SourceWrite a diagram fence and have your agent sync the file with sync_markdownPaste SVG by hand
PicturesCommit the generated .svg and .dark.svg filesLeave them out of git; the page would show broken images
FreshnessRun npx @buun_group/plotwork sync --check in CI; see Keep diagrams in sync in CITrust that nobody forgot to sync
EditsChange the fence, then syncEdit the generated block between the markers
PathsKeep the pictures in assets/diagrams next to the document, or choose a folder with assetsDirMove the files without syncing again

1. What GitHub does and does not render

GitHub draws Mermaid fences itself, in the page. It does not draw custom fences, and it will not run a renderer for them. Plotwork therefore renders before commit: the picture is a file in the repository, and the Markdown refers to it.

From fence to picture: 5 nodes, 5 connections. An author writes a diagram fence, sync renders it to SVG files and a picture block, and GitHub shows the picture.

2. What a sync produces

For each top-level diagram fence, a sync makes four changes. sync_markdown reads and writes no file itself: it returns the rewritten document and the SVG files, and the caller, usually your agent, saves them.

ChangeWherePurpose
A collapsed "Diagram source" sectionAround the fenceReaders see the picture first and can open the source.
A picture blockDirectly under the sectionAn HTML picture element: the light SVG by default, the dark SVG when the reader's color scheme is dark.
A collapsed "Text description"Inside the picture blockThe diagram as plain text, so it can be read without the image and by tools that skip images.
Two SVG filesassets/diagrams/<id>.svg and <id>.dark.svg next to the documentThe pictures. The id comes from the diagram title.

The picture block starts and ends with marker comments and carries a hash. The hash covers the source and the rendered output, so a change to the diagram or to the renderer makes the block stale and the next sync rewrites it. Do not edit between the markers.

A fence that is indented, for example inside a list item, is still rendered but is not wrapped in the collapsed section.

A picture written by a sync carries its diagram source in its metadata, so read_diagram can give the source back from the picture alone. See Editing an existing diagram.

3. Running a sync

Ask your agent: "Render the diagrams in README.md". The agent sends the whole file and its path to sync_markdown, then writes the markdown it gets back over the file and each entry of files at its path. The local server does this with no key and no account. The same operation is POST /v1/markdown/sync over HTTP, which needs an API key and the Pro plan; the quick start has a request you can run.

InputWhat it does
markdown and documentPathThe whole document as it is on disk, and where it lives, relative to the repository root with forward slashes. Picture links and file paths are worked out from the path.
modesync, the default, returns the rewritten document and the files to write. check changes nothing and reports whether a picture is stale.
assetsDirThe folder for the SVG files, relative to the repository root. The default is assets/diagrams next to the document.
prefixStarts every picture file name with this text. Use it when several documents share one asset folder.
convertMermaidWhen true, every Mermaid fence that can be converted becomes a diagram fence first. See Migrating from Mermaid.

A diagram with an error is a normal result, not a failure: its fence is left as it was, the report names its line and column inside the document with a hint, and the other fences still sync. The limits on the size of a document are in the tool reference.

4. Where the pictures show up

PlaceExpectedNote
GitHub README and Markdown filesYesGitHub documents the picture element with a color-scheme source for light and dark images.
Editor preview (VS Code and similar)YesRelative image paths load in the preview.
npm package pageUncertainnpm may refuse to show SVG images in a README.
MCP (Model Context Protocol) clientsNoA client receives text and cannot show an SVG. Use outline_diagram for the text form.
GitLab and other hostsProbablyThey need to allow SVG in an image tag.

5. Check your page after you push

CheckWhat to look for
Light modeThe light picture loads and the text is crisp.
Dark modeSwitching GitHub to a dark theme loads the dark picture, with readable text and visible lines.
Phone widthThe picture scales down to the screen and does not scroll sideways.
Collapsed sections"Diagram source" and "Text description" open and show their content.
Nested foldersA picture in a subfolder loads; its path goes up to the shared assets folder, for example ../assets/diagrams.
Alt textHovering or using a screen reader gives the diagram's summary.

Most failures come from a path that points outside the repository or from a picture file that was not committed.

6. Troubleshooting

SymptomCauseFix
The page shows a broken imageThe SVG is not committed, or the path movedSync the file again, then commit the SVG files next to the document.
A check with mode set to check says a block is staleThe fence or the renderer changedSync the file again and commit the result.
An SVG is left over after a diagram was renamed or removedA sync returns pictures and never deletes old onesDelete the unused files.
The fence shows as plain code on GitHubThe file was never syncedSync it, write the result, and commit.
Two documents show each other's pictureSame title in a shared asset folderGive each document its own prefix.

See also

DocWhy
Writing diagramsThe language by example
Writing diagrams with an agentThe validate and fix loop
How a diagram is drawnHow source becomes SVG