Bowen Zhen
← Projects & Thoughts

Excalidraw Notes Skills

· GitHub ↗
Node.jsExcalidrawSVGCLIAgent SkillsMarkdown

Inspiration: Excalidraw is great for thinking visually, but its .excalidraw JSON files do not embed nicely in markdown. Pasting a screenshot loses the source. Linking out breaks the flow. I wanted a workflow where diagrams live next to the prose that references them, the source is editable, and the rendered output is just a normal image link that works everywhere.

Core Features:

  • mdex CLI that builds every .excalidraw file under a directory into .svg next to its source
  • Convention of co-located *.assets/ folders, so each markdown doc owns its diagrams
  • Skill packages for Claude Code and OpenAI Codex, auto-discovered when dropped into the agent’s skills folder
  • Python builder template with layout helpers and validation for dense study-note scenes (Nunito text, card overflow, duplicate IDs, bound-arrow references)
  • Zero-config rendering: link to the SVG from markdown and it works in GitHub, Obsidian, VS Code preview, and static site generators

What I Learned Building It:

  • Boring conventions beat clever embedding. The earliest version tried to inline Excalidraw scenes directly into markdown with a custom code fence. It looked elegant and broke everywhere: GitHub stripped it, Obsidian rendered it differently, static generators ignored it. Switching to the boring convention, source file beside the markdown, build to SVG, link the SVG, made the workflow portable by construction. The lesson: when targeting many renderers, pick the lowest common denominator (a normal image tag) and put the cleverness in the build step.

  • Agent skills as a distribution format. The same workflow needed to work whether I was authoring by hand, asking Claude Code to draft a diagram, or asking Codex. Packaging the convention as a skill (instructions, schema reference, Python builder template, a small mdex shim) meant the agent could produce valid scenes without me re-explaining the rules each session. The skill folder is the unit of distribution: copy it into ~/.claude/skills/ or ~/.codex/skills/ and the next session picks it up.

  • Scene-specific Python builders for dense notes. For study notes from videos, papers, and long articles, hand-authoring Excalidraw JSON is tedious and error-prone. A Python template that emits scenes programmatically, with helpers for grids, cards, arrows, and Nunito text metrics, made dense layouts tractable. Validation (duplicate IDs, overflow, dangling arrow bindings) catches the failure modes that silently break renders in Excalidraw’s web app.

How It Works:

some-doc.md
some-doc.assets/
  architecture.excalidraw   source scene JSON (edit this)
  architecture.svg          generated artifact (do not edit)

Build with node src/cli.mjs build docs (or symlink to mdex on PATH). Commit both the source and the generated SVG. The markdown stays clean, the source stays editable, and the diagram renders anywhere markdown does.