How to Add Mermaid Diagrams to a Github Readme Without Breaking Live Preview
The "Just Paste It" Trap
You copy a mermaid code block from a colleague's README, paste it into your own, push to GitHub, and—nothing. The diagram renders as a wall of raw text. Or worse: it renders fine on GitHub, but your local markdown editor's live preview shows a broken code fence, and you spend the next 40 minutes wondering which side is actually broken.
Here's the misconception most developers carry: they assume mermaid syntax is universally supported across all markdown environments. It isn't. GitHub added native mermaid rendering in February 2022, but most standalone markdown editors—VS Code's default preview, Obsidian, Typora in certain configurations—handle mermaid blocks differently, if at all. The result is a split-brain workflow where your README looks perfect in one place and broken in another.
The real problem isn't mermaid itself. It's the assumption that "markdown is markdown." Every renderer has its own dialect, its own plugin ecosystem, its own quirks. If you write for GitHub's renderer without considering your local editor, or vice versa, you'll chase rendering bugs indefinitely.
Let's fix this properly.
Why Your Live Preview Breaks
The root cause is straightforward: GitHub's markdown renderer and your local editor's renderer are different engines. GitHub uses its own pipeline (built on CommonMark with custom extensions) that recognizes mermaid as a special code block language. When it encounters a fenced code block tagged with mermaid, it hands the content to mermaid.js and renders an SVG inline.
Your local markdown editor doesn't do this by default. Most editors treat all fenced code blocks the same way: they syntax-highlight the content and display it as a code block. That's why your mermaid diagram shows up as colored text inside a gray box instead of a rendered diagram.
There's a second, subtler issue: version drift. GitHub's mermaid renderer runs a specific version of mermaid.js (currently 10.9.x as of late 2024). If your local editor's mermaid plugin runs a different version—say, 9.x—diagrams that use newer syntax features like architecture-beta diagrams or updated flowchart syntax will render on one platform and fail silently on the other.
I've seen teams lose 2 to 3 hours per sprint to this exact mismatch. One developer writes a diagram in Obsidian, it renders locally, they push it, and the GitHub render fails because they used a syntax feature specific to mermaid 9.4 that GitHub's version handles differently. The diagram looks fine to them. Nobody else sees it.
The GitHub-First Workflow
Here's the principle that eliminates 90% of mermaid rendering issues: write for GitHub first, then make your local editor match. Not the other way around.
GitHub is the source of truth. Your README lives on GitHub. Contributors read it on GitHub. The local editor is a convenience tool for writing—not the final rendering target. When you invert this priority and optimize for your local editor first, you end up with diagrams that break on the platform where they actually matter.
The GitHub-first workflow is simple in practice:
- Write your mermaid diagram using syntax compatible with GitHub's current mermaid version
- Push to a branch and verify rendering on GitHub's preview
- Install or configure the matching mermaid plugin in your local editor
- Treat any local rendering discrepancy as a plugin configuration issue, not a syntax issue
This sounds obvious. Most developers do the opposite: they write locally, see the diagram render, push, and discover it's broken on GitHub. Then they debug the syntax when the actual problem is a version mismatch between their editor's plugin and GitHub's renderer.
Step-by-Step: Mermaid That Renders Everywhere
Step 1: Use the Correct Code Fence
GitHub recognizes mermaid diagrams when they're enclosed in a fenced code block with the language identifier mermaid. The syntax is:
```mermaid
flowchart TD
A[Start] --> B{Decision}
B -->|Yes| C[Action]
B -->|No| D[End]
```
Three backticks, the word mermaid, then your diagram code, then three closing backticks. No indentation. No extra attributes. No HTML wrapper tags.
The most common mistake here is using four backticks or adding language attributes like mermaid {theme: dark}. GitHub's renderer ignores these and may fail to recognize the block as mermaid. Stick to the minimal three-backtick fence.
Step 2: Validate Before You Push
Before committing, validate your diagram syntax using the Mermaid Live Editor at mermaid.live. This is non-negotiable. Paste your diagram code into the editor and confirm it renders without errors.
This step catches 95% of syntax issues before they reach your repository. The Mermaid Live Editor uses the latest mermaid.js release, which may be slightly ahead of GitHub's version, but any diagram that renders in the Live Editor with standard flowchart, sequence, or class diagram syntax will render on GitHub.
If your diagram uses experimental features or very recent syntax additions, check GitHub's mermaid version. As of October 2024, GitHub runs mermaid 10.9.x. You can verify this by checking GitHub's rendering changelog or simply testing on a feature branch.
Step 3: Bridge the Editor Gap
Once your diagram is validated and pushed, configure your local editor to render mermaid blocks. The approach depends on your editor, but the goal is always the same: get your local preview to match GitHub's output.
For VS Code, install the "Markdown Preview Mermaid Support" extension by Matt Bierner. This extension intercepts mermaid code blocks in VS Code's built-in markdown preview and renders them using a bundled version of mermaid.js. After installation, open your README with Ctrl+Shift+V (or Cmd+Shift+V on macOS), and mermaid blocks render inline.
One caveat: the extension's bundled mermaid version may lag behind GitHub's. If a diagram renders on GitHub but not in VS Code's preview, check the extension's release notes for version updates. As of this writing, the extension ships mermaid 10.6.x, which covers the vast majority of diagram types.
For Obsidian, mermaid rendering is built in. No plugin required. Obsidian's default mermaid support handles flowcharts, sequence diagrams, class diagrams, state diagrams, and Gantt charts. However, Obsidian runs its own mermaid version (currently 10.4.x), which means very new syntax features available on GitHub may not render locally. For standard diagrams, this is rarely an issue.
For Typora, mermaid support is native and robust. Typora updates its mermaid version regularly with each app release. If you're on a recent version (1.7 or later), your mermaid rendering should closely match GitHub's.
Step 4: Handle Syntax Edge Cases
Certain mermaid syntax patterns render differently across versions. Here are the ones I've seen cause issues repeatedly:
Quoted labels: GitHub's renderer handles quoted node labels (A["Label with (special) chars"]) consistently. Some older editor plugins struggle with special characters inside quotes. If a label contains parentheses, brackets, or quotes, always wrap the entire label in double quotes.
Subgraph styling: CSS-based subgraph styling (style subgraphId fill:#f9f) works on GitHub but may not render in all local editors. If you need consistent styling, use the simpler classDef approach instead.
Markdown links inside nodes: GitHub supports markdown links inside mermaid nodes (A["[Link](https://example.com)"]). This is a newer feature that some local editors don't render. If links inside nodes are critical, test both environments.
Editor-Specific Fixes
VS Code
VS Code's default markdown preview does not render mermaid diagrams. Out of the box, you'll see a code block with syntax highlighting. The fix is the "Markdown Preview Mermaid Support" extension, which is a one-click install from the marketplace.
After installation, there's one configuration tweak worth making. Open your VS Code settings file and add:
"markdown.preview.mermaidSupport": true
This ensures the extension's rendering is active even if another markdown preview extension is installed. I've seen cases where the "Markdown All in One" extension overrides the preview and disables mermaid rendering. This setting prevents that conflict.
If you're using the "Markdown Preview Enhanced" extension instead, mermaid support is built in. No additional extension needed. But be aware that Markdown Preview Enhanced uses its own rendering pipeline, which may produce slightly different visual output than GitHub's. The diagram structure will be correct, but colors, spacing, and font sizes may differ.
Obsidian
Obsidian's built-in mermaid renderer is solid for standard diagram types. The main issue Obsidian users face isn't rendering failures—it's version lag. Obsidian bundles a specific mermaid version with each release, and it may not match GitHub's current version.
If a diagram renders on GitHub but not in Obsidian, check whether you're using syntax introduced after Obsidian's bundled mermaid version. The fix is usually to simplify the syntax to an older, more compatible form.
One Obsidian-specific gotcha: Obsidian's markdown processor treats %% comments differently than GitHub. Mermaid supports %% as comment syntax, but Obsidian may strip or misinterpret these. If you use comments in your mermaid diagrams, test them in both environments.
Typora
Typora has the best out-of-box mermaid experience of any markdown editor I've used. Its native rendering is fast, accurate, and closely tracks GitHub's output. The main thing to watch for is Typora's version—if you're running an older Typora installation (pre-1.6), update to get the latest mermaid renderer.
Typora also supports live editing of mermaid diagrams. Click on a rendered diagram, and Typora opens the source code in an inline editor with live preview. This is genuinely useful for iterating on complex diagrams without leaving your editor.
The Image Fallback When All Else Fails
Sometimes you need a diagram to render everywhere—GitHub, every local editor, documentation sites, npm package pages—without any plugin requirements. In these cases, the most reliable approach is to render your mermaid diagram as an SVG or PNG and embed it as an image.
Here's the workflow:
- Design your diagram in the Mermaid Live Editor
- Export as SVG (preferred for scalability) or PNG
- Commit the image file to your repository (typically in a
docs/assets/directory) - Reference it in your README with standard markdown image syntax

This approach has a concrete tradeoff: the diagram is no longer editable in-place. If you need to update it, you regenerate the image from mermaid source. To manage this, keep the mermaid source code in a separate .mmd file alongside the image:
docs/assets/
├── architecture.mmd # Mermaid source
├── architecture.svg # Rendered output
└── data-flow.mmd # Another diagram source
└── data-flow.svg # Rendered output
This gives you the best of both worlds: universal rendering via the image, and an editable source file for future updates.
For teams where contributors frequently update diagrams, I recommend a hybrid approach: use live mermaid blocks in the README for diagrams that change often, and use exported images for stable, complex architecture diagrams that need to render everywhere. This balances editability with portability.
Habits That Keep Diagrams Stable
After maintaining mermaid diagrams across dozens of repositories and multiple editor environments, I've settled on a few habits that eliminate rendering issues:
Always validate in the Live Editor first. This takes 30 seconds and catches syntax errors before they enter your repository. If the Live Editor can't render it, neither can GitHub.
Keep diagram syntax simple. The more advanced mermaid features you use—custom CSS, complex subgraph nesting, markdown links inside nodes—the more likely you'll hit a rendering discrepancy. Use the simplest syntax that communicates your diagram's intent. A flowchart with 15 nodes and basic styling will render identically everywhere. The same flowchart with custom CSS classes and embedded links may not.
Pin your editor's mermaid version. If you're using VS Code with the mermaid preview extension, note the extension's bundled mermaid version. When GitHub updates its mermaid renderer (which happens roughly every 2 to 3 months), check whether your editor's version still matches. A version mismatch of one minor release (10.6 vs 10.9) is usually fine. A mismatch of a major version (9.x vs 10.x) will cause rendering failures.
Test on a feature branch. Never push mermaid diagram changes directly to main. Push to a branch, view the rendered diagram on GitHub's branch preview, and merge only after confirming it renders correctly. This sounds tedious, but it prevents broken diagrams from reaching your contributors.
Document your mermaid version expectation. Add a note to your repository's contributing guidelines specifying the mermaid syntax version your diagrams target. This helps contributors understand why a diagram that renders in their local editor might not render on GitHub, and vice versa.
The bottom line: mermaid diagrams on GitHub READMEs are reliable when you write for GitHub's renderer first and treat your local editor as a secondary rendering target. Validate syntax externally, keep your editor's mermaid plugin current, and use image fallbacks for diagrams that must render everywhere. Follow this workflow and you'll stop losing time to rendering discrepancies—and your README will look consistent whether someone reads it on GitHub, in VS Code, or in any other markdown editor.