Mermaid diagrams
Mermaid turns a few lines of text into a flowchart, a sequence diagram or a Gantt chart. It is not markdown: it is a code block that some renderers have learned to draw, which is why the same file is a picture in one place and a wall of arrows in another.
```mermaid
flowchart LR
A[Write the file] --> B{Renders?}
B -- yes --> C[Ship it]
B -- no --> D[Check the platform]
D --> A
````flowchart LR` is left to right; `TD` is top down. The shape comes from the brackets: `[]` a box, `{}` a diamond, `()` a rounded box.
```mermaid
sequenceDiagram
Browser->>Page: opens the file
Page-->>Browser: renders it locally
Note over Page: nothing is uploaded
```A solid arrow is `->>`, a dashed reply is `-->>`. Nothing else about the syntax matters until the diagram gets big.
It is a code block, and that is the point
There is no mermaid in any markdown specification. What exists is a convention: put the diagram source in a fenced block, label the fence mermaid, and hope the thing reading it knows what to do. Where it does not, the reader sees your source. That is not a failure mode to design around, it is the normal case on half the places a README ends up.
So the question is never "is my mermaid correct", it is "correct for which renderer". Every platform pins its own version and its own subset.
Ask the platform which version it has
Put info on its own line inside a mermaid block and GitHub renders the version it is running. It is the fastest way to find out why a diagram that works in the Mermaid Live Editor does nothing in a pull request: the editor is on the current release and the platform is not.
Why it did not draw
Two causes account for most silent failures, and neither is obvious from the error, where there is one. The first is a special character in a node label: a bracket, a parenthesis, a quote mark or a hash. Put the label in quotes, or use an entity code such as #quot; for a quote and #35; for a hash. The second is the word end in lower case, which breaks a flowchart outright. Capitalise any letter of it and the diagram comes back.
Dark mode
A diagram that is legible on a white page can be unreadable on GitHub's dark theme, because the platform picks the mermaid theme and your document does not. A directive on the first line takes it back: %%{init: {'theme': 'dark'}}%%, or neutral, which is the safest choice when you do not know which background the reader is on.
When it has to render everywhere
Export the diagram to SVG and commit the image, with the mermaid source kept next to it in an HTML comment or a separate .mmd file. You lose the diff-friendliness, which is the main reason to use mermaid at all, so only do it for the diagram at the top of a README that has to look right on npm as well as GitHub.
What usually goes wrong
- It is not markdown. Nothing in CommonMark or GitHub-flavoured markdown mentions mermaid; a renderer either special-cases the fence or shows your source.
- The version is the platform's, not yours. A diagram built in the Mermaid Live Editor can use syntax the platform has not shipped, and the failure looks like a syntax error in your diagram.
flowchartis newer thangraph. Some renderers, Azure DevOps among them, documentflowchartas unsupported and wantgraph LR. If nothing draws, that word is the first thing to try.- Click handlers and inline HTML are usually stripped. Mermaid's own default security level is
strict, which encodes HTML tags and disables click functionality, and renderers have little reason to loosen it for a diagram that arrived inside someone else's document. - A diagram that does not parse fails silently in some renderers and prints a red error box in others. Neither tells the reader what you meant.
- Long labels are the usual reason a diagram is unreadable. Mermaid lays out what you give it and will not wrap for you.
- The word
endin lower case breaks a flowchart. Capitalising any letter of it fixes the diagram, and nothing in the error says so.
Where it behaves differently
| Platform | Behaviour |
|---|---|
| GitHub | Renders in .md files, issues, pull requests, discussions and wikis. |
| GitHub's Markdown API | Does **not** draw diagrams; it returns the block as highlighted code. Anything rendering through it inherits that, npmjs.com included. |
| GitLab | Renders, on mermaid 11. On a self-managed instance a Cross-Origin-Resource-Policy header of same-site or same-origin makes diagrams fail silently. |
| Obsidian | Built in. Nodes can link to notes by giving them the internal-link class, though those links do not show up in the graph view. |
| Notion | Pick Mermaid as the code block's language, then switch the block between Code, Preview and Split. /mermaid creates one directly. |
| VS Code | The built-in markdown preview draws mermaid fences. No extension needed any more. |
| Azure DevOps | Eleven diagram types, entity-relationship, gitgraph and timeline included. The catch is the syntax subset: use graph rather than flowchart, and no ----> or HTML tags. |
| Docusaurus | Only after installing @docusaurus/theme-mermaid and setting markdown.mermaid to true. |
| Bitbucket Cloud | Does not draw a mermaid fence inside a .md file. The open request for it has been gathering interest for years; teams use a Marketplace app instead. |
| Slack and Discord | Neither draws diagrams. The block arrives as text, so a diagram pasted into a channel is read as source. |
| This viewer | Drawn in your browser, and only for documents that contain one, because mermaid is over a megabyte. |
Questions
Why does my diagram work on GitHub but not on npm?
Because npmjs.com renders your README through GitHub's Markdown API rather than through github.com, and that API returns the mermaid block as highlighted code. Drawing it is something the website does afterwards, in the browser. If the diagram matters on npm, commit an SVG.
Which mermaid version am I writing for?
Whichever one the platform ships, and they lag. Put `info` on its own line inside a mermaid block on GitHub and it renders the version. Check that before assuming your syntax is wrong.
Can I click a node and go somewhere?
Rarely. Most renderers run mermaid with its security level set to strict, which disables click handlers, because the diagram comes from whoever wrote the document. Obsidian is the useful exception: an `internal-link` class on a node links it to a note.
Which diagram types can I count on?
Flowcharts and sequence diagrams render everywhere mermaid renders at all. Class, state, Gantt, pie and entity-relationship diagrams are widely but not universally supported, and the newer types are where platform lag bites: a renderer pinned to an older mermaid will not know them. Azure DevOps publishes its list of eleven, which is the only platform that does.
Should I use mermaid or an image?
Mermaid while the diagram is changing, because it diffs like text and anyone can edit it in a pull request. An image once it is settled and has to render everywhere. The two are not exclusive: keep the source and commit the export.
Sources
Everything above was read from these, not from memory. If a page here disagrees with one of them, the vendor is right and this page is out of date.