Mermaid ER diagrams as native, editable Excalidraw — crow's-foot cardinality and clean layout.
An Obsidian plugin that renders Mermaid entity-relationship diagrams as
beautiful, editable Excalidraw drawings — not the rasterized image fallback
you get from @excalidraw/mermaid-to-excalidraw (which
does not natively support ER diagrams).
Website: merefolk.amberlogica.com · Support: Buy me a coffee ☕
Write a normal ```mermaid erDiagram block. Merefolk replaces it inline with a
hand-drawn Excalidraw render — crow's-foot cardinality, clean orthogonal
routing, non-crowding labels — and lets you open it in a full Excalidraw canvas
to edit, with your changes saved back and shown in the note.
[!NOTE] Merefolk isn't in the Obsidian community store yet. Until it is, install it via BRAT or build it from source — see Development.
Merefolk is desktop-only and requires Excalidraw 0.18+ to be installed and enabled (for crow's-foot arrowheads).
In any note, write a fenced ```mermaid block containing an erDiagram:
```mermaid
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE_ITEM : contains
CUSTOMER {
string name
string email PK
}
```
Switch to Reading view or Live Preview. Merefolk replaces the block inline with a hand-drawn Excalidraw diagram — crow's-foot cardinality, clean orthogonal routing, and real table rows. It scales to fit the note and repaints when you switch light/dark theme.
Hover the diagram and use the button group:
Edit in the canvas. Your changes save to a companion .excalidraw scene, and
the inline render prefers that saved scene from then on.
Changed your mind? On an edited diagram, use Re-sync from Mermaid to discard the saved scene and regenerate from the source block.
[!NOTE] The Mermaid text is the source of truth until your first edit — after that, the saved scene wins.
Three entry points open a diagram: the inline Open button, the command "Convert Mermaid ER diagram to Excalidraw", and the ribbon icon (Merefolk: ER → Excalidraw).
Open Settings → Merefolk.
| Setting | What it does | Default |
|---|---|---|
| Scene folder | Vault-relative folder where saved .excalidraw scenes are stored. |
.obsidian/merefolk/scenes/ (leave empty for default) |
[!NOTE] Changing the scene folder does not move existing scenes.
||, |o, o{, }o → Excalidraw
0.18 crow's-foot arrowheads).[keys] [type] [name] columns (one element per cell), and subtle row
separators..excalidraw scene and the inline render prefers it. A Re-sync button
discards edits and regenerates from the source.Mermaid `erDiagram`
└─ src/mermaid/parseER.ts parse -> ERModel (+ skipped lines)
└─ src/layout/elkLayout.ts ELK layered layout -> positions, edge routes, label positions
└─ src/excalidraw/emit.ts -> native Excalidraw elements (theme colors, crow's-foot)
├─ src/excalidraw/toSvg.ts exportToSvg -> inline render (Feature 2)
└─ src/view/* React canvas in an ItemView -> edit + persist (Feature 1)
Scene persistence: src/scene/ (stable %% merefolk:<id> block id + .excalidraw
files under .obsidian/merefolk/scenes/).
Merefolk isn't in the community store yet. To run it from source:
npm install
npm run dev # esbuild watch -> main.js
Symlink (or junction) this repo into a test vault's plugins folder so Obsidian loads it, then enable Merefolk under Settings → Community plugins:
# Windows (no admin needed): junction the repo into the vault
New-Item -ItemType Junction -Path "C:\path\to\Vault\.obsidian\plugins\merefolk" -Target (Get-Location)
npm run build # type-check + production bundle
Open test/sample-er.md (which also contains malformed/edge-case fixtures) to
exercise every path.
[!IMPORTANT] Requires Excalidraw 0.18+ — crow's-foot arrowheads (
crowfoot_one/crowfoot_many/crowfoot_one_or_many) don't exist before it.
default condition, so esbuild.config.mjs pins conditions: ["production"].
0.18 does NOT auto-inject its stylesheet, so it's imported and bundled as a
string via the .css -> text loader, then injected at runtime (src/globals.d.ts
declares *.css).x/y + points — otherwise
convertToExcalidrawElements derives NaN geometry, which cascades to a NaN
zoom and a call-stack overflow. Arrows use ELK's route points.elbowed doesn't route in a static export — elbow routing is
interaction-time only. We use ELK's orthogonal edge.sections for the arrow
points instead.initialData on a fresh mount, never setState from the
excalidrawAPI render-phase callback (infinite render loop).css-change event.@excalidraw/mermaid-to-excalidraw
dialog dep (cytoscape/katex, ~6 MB) via src/stubs/ — it's only lazily
imported and we never open that dialog.[keys] [type] [name] columns), one element per cell.mermaid dep).parseER / elkLayout (Vitest).If Merefolk is useful to you, you can support development:
MIT © Josh Quiachon / Amberlogica