beautiful-mermaid でゼロ依存の Mermaid 図を描く
ゼロ依存・DOM 非依存の beautiful-mermaid を Astro + MDX に組み込み、build 時の静的レンダリングと runtime のインタラクティブエディタを共存させた実装メモ。
検証日: 2026-05-09
使用バージョン:
beautiful-mermaid@1.1.3環境: Node 22.12 / Astro 6.3 / MDX 5
技術記事に 図 を入れたい場面はよくあるが、Mermaid 公式ライブラリ(mermaid)は重く、DOM 依存があるためサーバーサイドでの静的 SVG 生成が大変。
beautiful-mermaid は ゼロ依存・DOM 非依存 で SVG を同期 render できるので、Astro の build 時にそのまま図に変換できる。
利用形態は 2 つ:
- 静的に埋め込む(
<Mermaid />Astro コンポーネント、build 時 SVG) - 触れるエディタ(
<MermaidEditor />React コンポーネント、runtime 編集 + 即時再描画)
静的埋め込み 1 — Astro コンポーネント(build 時 SVG)
<Mermaid code={...} /> を MDX から呼ぶだけで、build 時に SVG が埋め込まれる。
シーケンス図も同じインタフェース。
触れる Mermaid エディタ
プリセットからテンプレートを選んで編集してみてください。左を変えると右が即座に再描画されます。
beautiful-mermaid(ゼロ依存、build/ runtime 両対応)。実装の中身
Astro コンポーネント(static)
サーバー側で renderMermaidSVG(code) を呼んで、結果の SVG 文字列を set:html で埋め込むだけ:
---
import { renderMermaidSVG } from "beautiful-mermaid";
interface Props {
code: string;
caption?: string;
maxWidth?: string;
}
const { code, caption, maxWidth = "100%" } = Astro.props;
let svg = "";
let error: string | null = null;
try {
svg = renderMermaidSVG(code);
} catch (e) {
error = (e as Error).message ?? "Mermaid render error";
}
---
<figure class="not-prose my-6">
<div class="overflow-x-auto p-4 border border-line rounded-lg" style={`max-width: ${maxWidth}`}>
{error ? <pre>{error}</pre> : <div set:html={svg} />}
</div>
{caption && <figcaption>{caption}</figcaption>}
</figure>
React コンポーネント(interactive)
ブラウザでも renderMermaidSVG が動くので、useMemo で code → SVG を再計算する interactive editor が組める:
import { useEffect, useMemo, useRef, useState } from "react";
import { renderMermaidSVG } from "beautiful-mermaid";
export function MermaidEditor({ initialCode }: { initialCode?: string }) {
const [code, setCode] = useState(initialCode ?? PRESETS[0].code);
const svg = useMemo(() => {
try {
return renderMermaidSVG(code);
} catch (e) {
return "";
}
}, [code]);
// ...textarea + preview の 2 列 layout
}
useMemo で code が変わるたびに再 render。beautiful-mermaid は同期 + ゼロ依存なので、setState の度に呼んでも安定して動く。
表示の調整(向き / サイズ / 余白)
ある程度のスタイル調整は Mermaid コード自体のディレクティブ で済む。
方向(graph LR vs graph TD)
TD = Top-Down、LR = Left-Right。横に長い図は LR が読みやすい。
Subgraph(クラスタリング)
関連ノードをグルーピングして見せたい時は subgraph。
サイズ調整(maxWidth prop)
<Mermaid maxWidth="480px" /> で図の最大幅を絞れる(コンテナに pad されて中央揃え)。
小さく見せたい補足図に有効。
つまずいたポイント
- 複数行コードを MDX に渡す時は template literal が安全 — 文字列リテラル内の改行は
\nでも\折返しでも書けるが、template literal が一番ストレスなし <を含むラベル(<ISBN>等)は<に置換しない(beautiful-mermaid は内部でエスケープしてくれる)%%{init: {...}}%%ディレクティブは v1 では未対応(theme カスタマイズはまだ限定的)mermaid公式と機能差:gantt/mindmap/journeyなどは v1 系では未サポート or 制限あり。要件次第で公式mermaid+ 別途 wasm ロードを選ぶ- 大きい図(50 ノード以上)は build 時間に効いてくる — 5 ノード × 10 図ぐらいまでが快適
評価
| 観点 | 評価 | コメント |
|---|---|---|
| 学習コスト | ◎ | API は render(code, { format }) の 1 つだけ |
| 依存 | ◎ | ゼロ依存(npm install で他に何も入らない) |
| 環境互換性 | ◎ | Node / browser / Deno / Bun いずれも動く |
| ダイアグラム種別 | ○ | flowchart / sequence / class / ER は OK、gantt / mindmap は限定的 |
| カスタマイズ | △ | テーマやフォントの細かい調整は v1 系では限定的 |
向く / 向かないケース
- 向く: 技術記事 / ドキュメントへの図埋め込み(flowchart / sequence / class / ER 中心)、サーバーサイド SVG 生成、AI agent の図出力
- 向かない: gantt や複雑な mindmap が必要な場面 → 公式
mermaidを browser ロード - 向かない: テーマ / 色 / フォントの厳密なブランド統制が必要な場面 → SVG を後処理するか、別のダイアグラムライブラリを検討
関連 Topic / 関連書籍
この記事と関係する tech-book.net の Topic と、それぞれの Topic に紐づく書籍:
Effective TypeScript(第2版) : 型システムの力を最大限に引き出す83項目
急速に普及が進んでいるTypeScriptの実用書! TypeScriptの実用書。TypeScript…
TypeScriptとReact/Next.jsでつくる実践Webアプリケーション開発
新しいフロントエンドの入門書決定版! 本書はReact/Next.jsとTypeScriptを用いてWebアプリケーションを開…
かんたん TypeScript
本書は、「広く・正しく・新しく」をコンセプトにTypeScriptでプログラミングをはじめるにあたって基本的なことはすべて学習できる内容となっています。また、イラストによる図解方式で概念をやさしく解説している…
ゼロからわかる TypeScript入門
プロを目指す人のためのTypeScript入門 安全なコードの書き方から高度な型の使い方まで
TypeScriptは、JavaScriptに静的型付けの機能を加えたオープンソースのプログラミング言語です。本書では、根幹となるJavaScr…