Agentic Mermaid

Your browser rendered the diagram below through the framework-neutral lazy ESM entry. Native import needs no bundler or import map, and only the selected diagram family is fetched. The diagram source never leaves the page.

<script type="module">
  import { renderMermaidSVGAsync } from
    'https://unpkg.com/agentic-mermaid@0.4.1/dist/browser-lazy/index.js'

  const svg = await renderMermaidSVGAsync(source, {
    style: 'zinc-dark',
    security: 'strict',
  })
  const parsed = new DOMParser().parseFromString(svg, 'image/svg+xml')
  if (parsed.querySelector('parsererror') || parsed.documentElement.localName !== 'svg') {
    throw new Error('renderer returned invalid SVG')
  }
  document.querySelector('#diagram').replaceChildren(
    document.importNode(parsed.documentElement, true),
  )
</script>

The version in that URL is pinned because the lazy entry first ships in v0.4.1. This page serves the identical entry and chunk graph from its own origin instead of unpkg, so the demo keeps working offline and makes no third-party request.

Keep strict rendering and parsed-node insertion for authored or user-provided source. For a strict Content Security Policy, self-host the module graph under script-src 'self', or allow the pinned CDN origin and authorize the initializer with an external file, nonce, or hash. This demo uses a same-origin module graph and a generated external initializer; it does not need 'unsafe-inline'.

Runs on Chrome 97, Firefox 104, Safari 15.4, Edge 97 and newer. docs/browser.md covers what sets that floor, how to pre-render at build time instead, and the two traps in rolling your own bundle.

Live render

The source

timeline
  title History of Social Media
  2002 : LinkedIn
  2004 : Facebook : Google
  2005 : YouTube
  2006 : Twitter

Should you use this?

Usually not. When the diagram source is already fixed at publish time, as it is in a blog post or a docs page, pre-render it during the build and send no renderer JavaScript at all. Use this lazy entry when the source or rendering options genuinely change in the browser. This Timeline path is about 162 KB gzip instead of the roughly 896 KB gzip all-family compatibility file.

Alpine, React, Vue, and other frameworks can call the same async function from their own lifecycle; the renderer itself has no framework dependency. See the browser recipe for pre-rendering, vanilla JavaScript, Alpine, and classic-script examples.