Mermish — the language merpeople speak. Now Neovim speaks it too.
A Neovim port of VS Code's Mermaid Preview
extension. Live-preview Mermaid diagrams from .mmd
files or fenced ```mermaid blocks in Markdown, synced as you type.
Pure Lua plugin. Zero install dependencies — your browser is the rendering engine. Real Mermaid.js output (flowcharts, sequence diagrams, Gantt charts, state diagrams, C4, and 15+ other diagram types), not a reimplementation.
- Neovim ≥ 0.10
- A web browser — Chrome, Chromium, Edge, or Brave for the default chromeless
app-mode preview window (
browser_mode = "app"); any browser works withbrowser_mode = "tab" - Network access to load mermaid.js from a CDN, or a locally cached copy
(
mermaid.source = "local")
{
"maureyesdev/mermish.nvim",
ft = { "mermaid", "markdown" },
opts = {}, -- use defaults, or pass your own config table
}use {
"maureyesdev/mermish.nvim",
config = function()
require("mermish").setup()
end,
}| Command | Keymap | Description |
|---|---|---|
:MermishPreview |
<leader>ap |
Open a live diagram preview |
:MermishClose |
<leader>ac |
Close the preview |
:MermishToggle |
<leader>at |
Toggle the preview |
:MermishExport [png|svg] |
<leader>ae |
Export the current diagram |
:MermishInfo |
Print current config |
All options are optional — setup({}) or setup() uses the defaults shown below.
require("mermish").setup({
-- Local preview server
host = "127.0.0.1",
port = 0, -- 0 = OS-assigned free port
-- Where the preview opens
auto_open_browser = true,
browser_mode = "app", -- "app" (chromeless Chromium-family window) | "tab"
browser_cmd = nil, -- nil = system default (open / xdg-open / wslview)
-- set to bypass browser_mode entirely
-- Rendering
theme = "auto", -- "auto" (follow &background) | "default" | "dark"
-- | "forest" | "neutral" | "base"
mermaid = {
source = "cdn", -- "cdn" | "local"
cdn_url = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",
local_path = nil, -- nil = stdpath("data") .. "/mermish/mermaid.min.js"
init = {}, -- extra keys merged into mermaid.initialize()
},
-- Sync
debounce_ms = 250,
follow_cursor = true, -- markdown: preview follows the mermaid block under cursor
-- Sources
filetypes = { "mermaid", "markdown", "markdown.mdx" },
-- Diagnostics
diagnostics = {
enabled = true,
severity = vim.diagnostic.severity.ERROR,
},
-- Export
export = {
dir = nil, -- nil = browser download; path = server-side save
format = "png",
scale = 2,
},
-- Keymaps
default_keymaps = true,
keymaps = {
preview = "<leader>ap",
close = "<leader>ac",
toggle = "<leader>at",
export = "<leader>ae",
},
})browser_mode = "app" (the default) opens the preview in a chromeless,
toolbarless window using a Chromium-family browser's --app= flag — a single
dedicated window instead of a tab in your regular browsing session, while still
being the same live, interactive page (pan/zoom/export all still work; it's not a
screenshot). mermish looks for Google Chrome, Chromium, Microsoft Edge, or Brave
Browser, in that order. If none is found, it falls back to browser_mode = "tab"
with a one-time warning.
browser_mode = "tab" opens the preview URL in your system's default browser, in
a normal tab, the way earlier versions of mermish always did.
Set browser_cmd to bypass browser_mode entirely and use your own opener
command verbatim.
App-mode windows run in their own dedicated browser profile (separate from your
regular Chrome/Edge/Brave profile — no shared cookies, extensions, or logins,
which isn't needed for previewing a diagram), so mermish can close the window on
:MermishClose/:MermishToggle instead of leaving it open with a dead page.
Reopening the preview after the window was closed (by you, or by mermish) always
spawns a fresh one.
Built in phases; all shipped:
- Phase 0 — scaffold, config, health, command stubs
- Phase 1 — HTTP server + static page serving
- Phase 2 — preview open/close flow for
.mmdfiles - Phase 3 — live sync (debounced, via SSE)
- Phase 4 — pan/zoom + reset toolbar
- Phase 5 — error surfacing (mermaid parse errors → buffer diagnostics)
- Phase 6 — markdown-embedded
```mermaidblock detection - Phase 7 — export (PNG/SVG)
- Phase 8 — chromeless app-mode preview window (default), isolated browser profile, real open/close lifecycle
The preview opens either in a dedicated, chromeless app-mode window (default,
browser_mode = "app") or a normal tab in your system browser
(browser_mode = "tab") — see Preview window mode
above. A Neovim-buffer rendering mode was separately prototyped and dropped
(a headless-Chrome screenshot per edit has no live interactivity: pan/zoom/export
only work against a real, running page).
:checkhealth mermishmake test-setup # install plenary.nvim to /tmp
make test # run all unit tests
make lint # check formatting with stylua