See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
One route survives GitHub's sanitizer: an image by URL
GitHub runs rendered markdown through an HTML sanitizer before it reaches the page. Script tags, style tags, and iframes are removed outright, which rules out every interactive embed. What survives is a small allowlist that includes images, so the way to show a diagram that changes without commits is a plain markdown image pointing at a URL that re-renders when the diagram does.
A Datadef project shared public gets exactly that: a permanent image endpoint that reflects the current state of the diagram. Paste it into the README like any other image. The endpoint takes optional sizing parameters, format png or jpeg, width 600 to 4000, height 400 to 4000, and scale 1 to 3, with a default of 1600x1000 at 2x that is already sharp for a README.
 <!-- Sized wider for a README that leads with the diagram --> 
What Camo does to your image URL
You will notice that the rendered README never loads your URL directly. GitHub rewrites every external image to its anonymizing proxy at camo.githubusercontent.com, so the reader's browser talks to GitHub, and GitHub fetches from the origin. This protects reader IP addresses from external servers, and it means update latency is decided by how Camo caches.
Camo caches by URL and honors the cache headers the origin sends. An origin that sends nothing can see its images cached for a very long time, which is where the folklore about READMEs showing week-old images comes from. Datadef serves the embed with Cache-Control max-age=300, so Camo re-checks the origin every five minutes and an edited diagram shows up in the README within minutes, not on the next commit.
If a copy ever seems stuck, Camo supports an explicit purge: send an HTTP PURGE request to the camo.githubusercontent.com URL you see in the rendered page (curl -X PURGE followed by that URL) and the next view re-fetches. One more timing note from the origin side: the first render after an edit is produced by a headless browser and can take a few seconds, then it is cached.
Relative paths, absolute URLs, and what live actually means
A relative path in README markdown, like docs/architecture.png, resolves to a file in the repository at the branch being viewed. That image is versioned with the code, which is tidy, and stale by construction: it only changes when someone regenerates the file and commits it. An absolute URL to a live endpoint inverts that trade. The README markdown never changes again; the pixels behind it do.
The two compose. Teams that want the diagram versioned per release can keep a committed export for tags and the live URL on the default branch, or regenerate the committed file in CI on merge. The CI recipe is covered in a living diagram from GitHub Actions.
Dark mode with the picture element
GitHub's sanitizer allows the picture element, and GitHub documents it as the supported way to show theme-aware images: a source tag with media set to prefers-color-scheme dark, and an img fallback. Readers on the dark theme get the dark asset, everyone else gets the fallback.
This works with any pair of image URLs, including one live URL plus a committed dark export, or two live URLs if you keep a dark variant of the diagram as its own shared project. Check how your diagram reads on the dark theme before deciding you need the second variant; a render that carries its own background often reads fine on both.
<picture> <source media="(prefers-color-scheme: dark)" srcset="docs/architecture-dark.png"> <img alt="System architecture" src="https://datadef.io/api/embed/my-platform-a1b2c3d4"> </picture>
Native Mermaid: the in-repo alternative and where it stops
GitHub renders Mermaid natively in fenced code blocks, and for small flows it is the right tool: the diagram source lives in the same commit as the prose, reviews like code, and needs no external service. A sequence diagram of one handshake or a five-box flow belongs in a Mermaid fence.
The limit is layout. Mermaid computes it, and past roughly 20 nodes, or when you need zones, groupings, and column-level detail, generated layout stops being readable. That is the point where a rendered diagram with deliberate layout earns the external URL. The general markdown trade-offs, including this one, are covered in embed diagrams in Markdown.
Keeping the README diagram true after the code changes
The live URL removes the re-export and re-commit step, not the edit itself. When the architecture changes, someone or something still updates the diagram. The manual loop is fine for slow-moving systems: edit in Datadef, and every README showing the embed follows within minutes.
The automated loop uses the Datadef MCP server, registry name io.datadef/mcp. An agent connected to it, Claude Code or Cursor in practice, can read the repository and update the diagram to match: after a merge, on a schedule, or when asked during review. To be exact about the boundary: Datadef does not watch your repository and nothing detects code changes on its own. The regeneration is one agent call or one CI command away. Connecting an agent needs an API key, available on paid plans. The broader workflow is in keep your README in sync with code.
Honest limit
FAQ
How do I embed an architecture diagram in a GitHub README?
Why does my README image not update after I changed the diagram?
Can I embed an iframe in a GitHub README?
Does a live diagram embed work in a private repository README?
Should I use Mermaid or an image URL for a README architecture diagram?
How do I show a dark mode diagram in a GitHub README?