
[August 2026 edition]
Embedding Animated Diagrams in Astro Markdown with Starch
Published: Aug 19, 2026
Reading time: ~4 min
We introduced animation as a way to explain abstract concepts and complex processing flows more clearly in blog articles.
On this site, we added an <animated-diagram> component that displays diagrams defined with the Starch DSL in Markdown. This article presents the actual result and how we wrapped Starch for the site.
What is Starch?
Starch is a DSL for defining shapes, paths, and changes over time as text, then rendering an animated diagram in the browser from that definition.
Shapes and paths go in objects, and time-based changes go in animate. In the following example, a packet moves from the start of a path to its end over two seconds.
DSL
name "Starch basics"
background #071015
viewport 480x260
style routeStyle
stroke #557c50 width=3
objects
route: path (60,120) (420,120) @routeStyle
packet: ellipse 24x24 fill #a6d65f pathFollow=route pathProgress=0
start: text "start" size=14 fill #eaf4f6 at 60,165
end: text "end" size=14 fill #eaf4f6 at 420,165
animate 2 loop easing=linear autoKey=false
0 packet.transform.pathProgress: 0
2 packet.transform.pathProgress: 1Starch rendering result
objects defines the path and packet, while animate changes pathProgress from 0 to 1. Starch loads this definition and renders the diagram for the current time as SVG.
The diagram we embedded
In this example, one animated diagram compares Stateful MCP and Stateless MCP. Readers can see the sessions, Instances, authentication paths, and packet movement in one diagram.
The player supports play, pause, restart, and seeking. Diagrams with chapters support previous and next chapter controls, and the expand button opens the diagram at full-screen size.
The browser loads the DSL and renders the SVG for the current time from the diagram definition. Readers can therefore seek to an intermediate state.
Display it from Markdown
In this implementation, the article provides a custom element with the public DSL URL and a description of the diagram.
<animated-diagram
src="https://example.com/diagram.starch"
aria-label="A comparison of Stateful MCP and Stateless MCP"
autoplay
></animated-diagram>src provides the public DSL URL, and aria-label describes the diagram. The article only needs to provide the diagram definition and description.
How we wrapped Starch
We leave diagram rendering to Starch and add article-facing display and controls in this site’s component. When the custom element connects in the browser, it fetches the DSL and passes it to StarchDiagram.
The core of the implementation is:
const source = this.getAttribute('src');
if (!source) {
this.showError(`${this.copy.failed} src is required.`);
return;
}
const response = await fetch(source, { signal: this.abortController.signal });
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
const dsl = await response.text();
this.diagram = new StarchDiagram(stage, {
autoplay: false,
onEvent: () => this.syncControls(),
});
const result = this.diagram.setDSL(dsl);
if (!result.ok) throw new Error(result.error);
this.dataset.ready = 'true';
this.dataset.warningCount = String(result.warnings.length);
this.dataset.duration = String(this.diagram.duration);
this.range.max = String(this.diagram.duration);The wrapper fetches the DSL, connects StarchDiagram to the stage, and parses it with setDSL. It displays an error when parsing fails and passes the duration to the seek bar when parsing succeeds. Starch renders the SVG; our component handles the article-facing controls.
Features added as a component
This component groups the features that improve accessibility for animated diagrams and provide playback controls such as play, pause, and seeking:
- play, pause, restart, seek, chapter navigation, and full-screen display
role="img",aria-label, labelled controls, and playback-status announcements- a still frame when
prefers-reduced-motionis enabled - an error message when loading fails and fallback text when JavaScript is unavailable
- responsive sizing and larger controls for pointer-based interaction
The Starch definition and description vary by diagram. Playback and accessibility behavior live in the shared component, so we do not reimplement the same behavior for each article.
Why VHS and Starch use different embed syntax
With VHS, the Astro build generates MP4, GIF, or PNG files from a VHS tape, then displays those generated files as HTML in the article. The browser plays or displays the generated files.
Starch loads a DSL in the browser instead of displaying a completed video. <animated-diagram> fetches the DSL, passes it to StarchDiagram, and renders an SVG for the current time. The component also manages the live state, such as seeking and reduced motion.
For this reason, we use a Markdown video code block to specify generated VHS media, while we use a browser-side custom element for Starch. We show the Starch DSL in a code block so it is easy to read, and use <animated-diagram> for the actual animation.
Summary
On this site, we added a component that embeds Starch animation diagrams in Markdown so that abstract concepts and complex processing flows are easier to explain in articles.
- Starch defines shapes, paths, and changes over time
- the component loads the DSL and lets Starch render the SVG
- the shared component provides controls, accessibility, and error display
- MCP structure and state changes can be explained with an animation