ブログとWEBアプリ
2025-12-02

claude code に鞭を打って、ER図を描くツールを作ってみた。
rusterdは、ER図(エンティティ関連図)をテキストで記述し、SVGにレンダリングするDSLコンパイラ。
リポジトリ: https://github.com/misebox/rusterd
デモ用ページ: /pages/rusterd-demo/
Rustで実装されており、wasm-packでビルドしたものをnpmパッケージとして公開しているので、ブラウザでも動作する。
cargo build --release
rusterd input.erd -o output.svg
bun add rusterd
erdToSvg()関数を使用してERD記法からSVGを生成できます。
import init, { erdToSvg } from 'rusterd';
await init();
const svg = erdToSvg(erdSource);
ただこれ、XSSに怯えながら使うことになりそう。
reactだとdangerouslySetInnerHTMLを使うことになる。
大丈夫だと思うけど、ユーザー入力を直接渡すのは怖いのかもなぁ。
import React, { useEffect, useState } from 'react';
import init, { erdToSvg } from 'rusterd';
export function ERDiagram({ erdSource }) {
const [svg, setSvg] = useState('');
const [ready, setReady] = useState(false);
useEffect(() => {
let mounted = true;
(async () => {
await init();
if (mounted) setReady(true);
})();
return () => { mounted = false; };
}, []);
useEffect(() => {
if (!ready) return;
try {
const out = erdToSvg(erdSource);
setSvg(out);
} catch (e) {
console.error('Failed to render ERD:', e);
setSvg('<svg xmlns="http://www.w3.org/2000/svg"><text x="10" y="20">Render error</text></svg>');
}
}, [ready, erdSource]);
return (
<div
className="erd-svg"
dangerouslySetInnerHTML=
/>
);
}
// 使用例
// <ERDiagram erdSource={`
// entity User {
// id int
// name string
// }
// @hint.arrangement {
// User at (0,0)
// }
// `} />
「ERD記法」は、オリジナル記法で、エンティティ、属性、リレーションシップを簡潔??に記述できる。
(自分で書いてみると結構面倒だったので、改良の余地あり。)
entity Category {
id int pk
parent_id int fk -> Category.id
name string not null
}
entity Product {
id int pk
category_id int fk -> Category.id
name string not null
}
rel {
Category 1 -- * Product
}
# Grid-based layout
@hint.arrangement = {
Category;
Product
}
# view product only
view product {
include Product
}
ER図を自動生成するとレイアウトが見づらくなりがちなので、表示を調整するために、グリッドベースで配置を制御するarrangement機能を用意している。
@hint.arrangementを使用することで、グリッドベースでエンティティの配置を制御できる。
@hint.arrangement = {
Category;
Product
}
viewブロックを使用して、特定のエンティティや関連だけを抽出した図を生成できる。
これにより、いちいち部分的なER図を別々に書かなくても済む。
# view product only
view product {
include Product
}
表示内容を以下のレベルで制御できる。
同じERD記法から異なる詳細レベルの図を生成できる。
テーブル数が増えたときにごちゃごちゃするときは、一旦テーブル名だけで表示してみたりもできる。
CLI
rusterd input.erd -o output.svg --detail pkfk
JavaScript
const svgPkOnly = erdToSvg(erdSource, { detail: 'pk' });
const svgAll = erdToSvg(erdSource, { detail: 'all' });