DEV Community

Cover image for How to Render Mermaid Diagrams in Neovim (Zero Node.js Dependencies)
coder7475
coder7475

Posted on

How to Render Mermaid Diagrams in Neovim (Zero Node.js Dependencies)

Learn how to preview and interact with Mermaid diagrams and Markdown directly from Neovim using a lightweight, pure-Lua local server.


The Problem with Mermaid in Neovim

Mermaid has become the de facto standard for writing diagrams as code. Whether you are sketching system architecture, sequence diagrams, state machines, or user journeys, keeping your diagrams alongside your documentation in Markdown (.md) files is a massive productivity boost.

However, Neovim does not render diagrams natively. Over the years, developers have experimented with several workarounds, each with its own compromises:

Solution How it works Trade-offs & Limitations
md-render.nvim Renders in floating window / buffer split Requires @mermaid-js/mermaid-cli (mmdc) via Node.js
mermaider.nvim + image.nvim Inline images inside the terminal Requires Kitty graphics protocol (Kitty/WezTerm/Ghostty) + mmdc
markdown-preview.nvim Browser preview Requires Node.js and a Yarn build step; heavy dependencies
vellum.nvim Split window rendering Requires headless Google Chrome/Chromium installed
mdkite.nvim + kitehost.nvim Instant browser preview with interactive SVGs Zero npm/Node.js dependencies, pure Lua server, works anywhere

If your terminal does not support the Kitty graphics protocol (or if you don't want to install global Node.js CLI tools and headless browsers just to preview a diagram), mdkite.nvim is by far the cleanest solution.


Why mdkite.nvim?

mdkite.nvim (formerly markdown-preview.nvim) is paired with kitehost.nvim, a tiny local HTTP server built completely in Lua using Neovim's built-in vim.uv event loop.

Key Highlights:

  • Zero npm / Node.js requirements: No need for npm install -g @mermaid-js/mermaid-cli or background headless browser binaries.
  • First-Class Interactive SVGs: Mermaid diagrams render with full interactive controls: zoom, pan, click-to-expand, and SVG export.
  • Real-time Live Sync: Uses Server-Sent Events (SSE) to update the browser preview as you edit, with cursor scroll synchronization.
  • Math & Syntax Highlighting: Includes KaTeX for LaTeX equations ($...$, $$...$$) and syntax highlighting for code fences.
  • Standalone Mermaid Files: Supports both .md documents and standalone .mmd / .mermaid files.

Step-by-Step Installation (lazy.nvim & LazyVim)

Step 1: Create the Plugin Spec

If you are using LazyVim or a standard lazy.nvim directory structure, create a new file at lua/plugins/mdkite.lua (or add this to your plugin list):

-- ~/.config/nvim/lua/plugins/mdkite.lua
return {
  {
    "selimacerbas/mdkite.nvim",
    dependencies = { "selimacerbas/kitehost.nvim" },
    cmd = { "MdKite" },
    ft = { "markdown", "mermaid" },
    opts = {
      instance_mode = "takeover", -- "takeover" (single tab) or "multi" (tab per file)
      port = 0,                  -- 0 = automatic port selection
      open_browser = true,       -- Automatically launch default browser
    },
    keys = {
      { "<leader>mp", "<cmd>MdKite<cr>", desc = "Markdown / Mermaid Preview" },
      { "<leader>ms", "<cmd>MdKite stop<cr>", desc = "Stop Preview Server" },
      { "<leader>mt", "<cmd>MdKite toggle<cr>", desc = "Toggle Preview" },
      { "<leader>mr", "<cmd>MdKite refresh<cr>", desc = "Refresh Preview" },
    },
  },
  {
    -- Add Mermaid syntax highlighting to Treesitter
    "nvim-treesitter/nvim-treesitter",
    opts = function(_, opts)
      if type(opts.ensure_installed) == "table" then
        vim.list_extend(opts.ensure_installed, { "mermaid" })
      end
    end,
  },
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Install the Plugins

Restart Neovim or run:

:Lazy sync
Enter fullscreen mode Exit fullscreen mode

Neovim will automatically clone kitehost.nvim, mdkite.nvim, and install the mermaid Treesitter grammar parser for rich syntax highlighting inside code fences.


How to Use It

1. Keybindings Cheat Sheet

Open any .md or .mmd buffer and use these shortcuts:

Shortcut Command Action
<leader>mp :MdKite or :MdKite start Launch the server and open preview in your browser
<leader>mt :MdKite toggle Toggle live preview on or off
<leader>ms :MdKite stop Shut down the local background server
<leader>mr :MdKite refresh Force a manual reload of the preview tab

2. Testing with an Example Diagram

Create a test file test-diagram.md in Neovim:

# Architecture Overview

Here is an architectural flow rendered via Mermaid:

```mermaid
flowchart TD
    Client["Client App (Android / Web)"] -->|HTTPS / WSS| API["API Gateway"]
    API --> Auth["Auth Service"]
    API --> Core["Core Backend"]
    Core --> Cache[("Redis Cache")]
    Core --> DB[("PostgreSQL DB")]
```

## Sequence Flow

```mermaid
sequenceDiagram
    autonumber
    actor User
    participant App as Neovim (mdkite.nvim)
    participant Server as kitehost.nvim (Lua)
    participant Browser as Web Browser

    User->>App: Press <leader>mp
    App->>Server: Start local HTTP daemon
    Server->>Browser: Open preview via SSE
    Browser->>User: Display interactive SVG diagram
```
Enter fullscreen mode Exit fullscreen mode

Hit <leader>mp (or type :MdKite). Your default browser will instantly pop open displaying rendered SVGs with pan, zoom, and live reload on save!


Standalone .mmd Files

If you prefer keeping diagrams in standalone files rather than embedding them in markdown documents, Neovim and mdkite.nvim support .mmd files natively:

  1. Create a file named workflow.mmd:
graph LR
       A[Draft] --> B(Review)
       B --> C{Approved?}
       C -->|Yes| D[Deploy]
       C -->|No| A
  1. Run :MdKite. The plugin will serve the standalone diagram on a clean canvas.

Summary

You don't need heavy Node CLI wrappers, external graphics protocols, or headless browsers just to view Mermaid diagrams from Neovim. By combining mdkite.nvim with kitehost.nvim, you get:

  • Fast, zero-config startup
  • Interactive vector diagrams that you can pan, zoom, and copy
  • Real-time live synchronization as you type
  • A fully native Lua configuration that fits right into modern Neovim setups

Top comments (0)