All work

Open source · Design engineer · Oct 2026

A diagram skill, built for chat

Most Mermaid skills help an agent write a diagram. This one helps you build a chat that knows when to draw one, never shows a broken one, and looks considered in light and dark. It’s what I learnt shipping diagrams in Strive’s chat, rebuilt so any chat can use it.

My part
Designed and built it, pairing with Claude Code
Tested on
Mermaid 12.2, two rounds of a wiring test
Status
Published in my skills repo
Link
GitHub
Same source, two looks.

Why

Easy to turn on, hard to get right

  • Turning on Mermaid in a chat is a prompt line away. Making it good isn’t. Every team that adds it meets the same four walls: it draws for everything, shows broken diagrams, looks generated, and trusts whatever the model writes.
  • I’d worked through all four shipping diagrams in Strive’s chat. So I wanted anyone to get there too: good-looking, meaningful diagrams from the first wiring, without inheriting my product to get them.
Rendering a diagram is solved. Knowing when to draw one isn’t.

Research

What’s out there today

  • Before writing a line, I read 15 public Mermaid skills from source, not from listings. They’re good at what they do, and nearly every one is for docs or images: an agent writing a diagram into a file. The one that touched a chat covered only the renderer.
  • A chat needs different things. Only three say when not to draw, the few that check a diagram do it while the agent writes, colours are fixed for light mode, and none strips model styling or tests when the model draws. That gap is what this skill fills.
What a chat needs, compared
draw-diagramsMost Mermaid skills
Who it’s forA chat where your model draws for your usersAn agent writing diagrams into docs or images
When to drawA tool that decides when. Numbers go to charts, one diagram per answerMostly how to draw. 3 of 15 say when not to
CheckingThe real parser on every call, a repair hint, one retry, then proseA few check, and only while the agent writes
When it breaksNothing shows, live or on reloadA broken diagram or raw source can show
LookMeaning mapped to your theme, in light and darkTheme presets, or colours fixed for light mode
Model stylingStripped, so the theme always winsKept. Some still recommend a deprecated directive
AccessibilityMeasured contrast, a 10px text floor, a name for screen readersA few mention contrast
SecurityModel output is untrusted. HTML and links are strippedRarely covered
ProofAn eval of when it draws, and a fresh agent building from itNo test of when it draws

The idea

Built for the chat, not the doc

  • Teaching a model to write Mermaid is one layer. A chat needs four: a tool whose description decides when to draw, guidance that teaches how, a gate that runs the real parser on every call, and a renderer that draws only what the gate accepted.
  • When to draw is the product, so it’s the part that gets measured: an eval of six prompts that should draw and four that shouldn’t, run through your real chat, before and after every prompt change.
Most skills are only the second box.

Care · accessibility

Readable by everyone

  • Contrast is measured, not assumed. The quiet grey connectors I’d carried over came out at 2.56:1, under the 3:1 a line needs. They’re 4.8:1 now, and a dash, not a paler grey, says “optional”.
  • Meaning never rides on colour alone: the label says it, the main path is thicker as well as coloured, and muted steps are dashed. Text never drops under 10px, measured per diagram, and every diagram is named for screen readers from its title and caption.
Contrast for the default palette (WCAG ratio)
PairLightDarkNeeds
Labels on steps and washes14.5–17.711.0–16.14.5
Muted text: edge labels, headings4.6–4.86.3–6.94.5
Connectors4.6–4.83.4–3.73
The main path5.27.03
Outcome borders on their wash4.7–5.95.1–7.33

Care · theming

Meaning, mapped to any theme

  • The model never picks a colour. It marks what a step means: the main path, the step that matters, a good, at-risk or bad outcome, or something out of scope. The theme decides how that looks, in light and dark.
  • Colours are named by role, with Tailwind defaults you can swap for your own, even oklch tokens. Along the way it fixes what Mermaid gets wrong on its own: a grey shadow that glows in dark mode, hard-wired journey colours, and arrowheads that ignore the main path.
  • ==>The one main path
  • :::accentThe step that matters
  • :::success / warning / dangerGood, at-risk and bad outcomes
  • :::mutedOut of scope
  • -.->Optional, or a loop back
The model says what a step means. Your theme decides how it looks.

Care · reuse and safety

Copy it, don’t adopt it

  • It works with any framework and the main model providers: tool definitions for Anthropic, OpenAI and the Vercel AI SDK, all type-checked, and four code files you copy as they are. The server gate fails open, so an outage never blocks chat.
  • The source is model output, so it’s treated as untrusted. With Mermaid’s strict mode on, an image tag and a click link still got through, so the renderer strips HTML, links and styling before Mermaid sees them.
Treat it like any input you didn’t write.

Design calls

The calls, and why

  • Every default in the skill has its reason written next to it, so you can argue with it instead of guessing.
  • Many of the calls are about restraint: what to leave out, turn off or wait for, so a diagram only shows up when it’s right.
Calls I made, and why
The callWhy
A skill, not a packageNo dependency to keep in sync. You copy what your stack needs and own it.
A generic look, not my design systemNobody should have to inherit my tokens to get a good diagram. Rules and Tailwind defaults travel.
Framework-neutralChats are built on everything. The core is plain code, with notes for React, Vue, Svelte and plain JS.
Draw only after the server’s verdictDrawing as soon as the arguments arrived flashed diagrams the server then rejected.
Fail openA validator outage must never block chat. The browser parses again and hides anything broken.
One retry, then proseA second failure rarely fixes itself, and the user is waiting.
Class, requirement, git and C4 off by defaultThey parse, but haven’t passed the light and dark check. Turning one on is one line.
A caption that’s a string, not nullIt stays valid under every provider’s strict tool mode.

Proof

Tested before trusted

  • Every rule was rendered on Mermaid 12.2, in light, dark and at phone width, before it was written down. Pitfalls other skills still repeat were checked too: one no longer applies, and one (a---ops) silently draws the wrong thing.
  • Then a fresh agent built a chat from the skill alone, with a stubbed model. Round one found a blocker: the retry never ran. Round two resolved 12 of 15 issues and surfaced six more, all fixed.
A reread can’t find what a stranger trips on.

Misses & lessons

What I’d tell day-zero me

  • MissPlanned to ship my product’s theme as code.

    LessonShare the rules, not the tokens. A DESIGN.md and Tailwind defaults travel. My design system doesn’t.

  • MissSet a fixed shrink floor, 75% and then 80%. Labels still dropped under 10px on a phone.

    LessonMeasure, don’t assume. The renderer now reads the smallest text in each diagram.

  • MissTrusted Mermaid’s strict mode with model output.

    LessonTest with a hostile input. An image tag and a link got through, so the renderer strips them first.

  • MissCalled the docs done once they read well.

    LessonHand them to a stranger. A fresh agent found a blocker in its first build.

A diagram should earn its place. This skill is how any chat makes sure it does.
The skill · open source Want diagrams in your own chat? Wire them up with draw-diagrams: the tool, the gate, the renderer, the look and an eval, with tested code to copy. npx skills@latest add marigameo/skills Open it on GitHub

Where it started: Diagrams in Strive chat.

Back to all work