mdv

July 2, 2026 · View on GitHub

A CLI tool that renders Markdown files in the browser with GitHub-style formatting and live reload on file changes.

Demo

mdv demo

Features

  • GitHub Flavored Markdown (GFM) — tables, strikethrough, autolinks, task lists
  • Server-side syntax highlighting via Chroma — no client-side JS
  • Mermaid diagrams from fenced mermaid blocks, rendered in-browser on demand
  • Live reload via SSE — browser updates without full page reload, scroll position preserved
  • PDF export — --pdf output.pdf flag (headless Chrome) or "Export PDF" button in the browser
  • HTML export — --html output.html flag saves the fully rendered, self-contained page
  • Serves relative local assets from the Markdown directory (e.g. ![demo](./recording.gif))
  • Auto-increments port if the default is taken (up to 20 attempts)
  • Binds to 127.0.0.1 only — no LAN exposure

Install

go install github.com/Allra-Fintech/mdv@latest

Or via Homebrew:

brew tap Allra-Fintech/tap
brew install Allra-Fintech/tap/mdv

Note: There is an unrelated Python tool also named mdv in homebrew-core. Use the fully-qualified name Allra-Fintech/tap/mdv to install this one.

Or build from source:

git clone https://github.com/Allra-Fintech/mdv
cd mdv
make install        # installs to ~/.local/bin (default) as mdv
# PREFIX=/usr/local make install   # custom prefix

Make targets

TargetDescription
make buildBuild ./mdv binary in the project directory
make installBuild and install to $PREFIX/bin (default: ~/.local/bin)
make uninstallRemove installed binary
make cleanRemove local ./mdv binary
make test-unitRun unit tests
make test-integrationRun integration tests (live reload, routing, PDF/HTML export)
make testRun all tests
make formatFormat code with go fmt
make lintLint with go vet

Usage

mdv [flags] <file.md>

Flags

FlagTypeDefaultDescription
--portint7777HTTP port (auto-increments if taken)
--no-browserboolfalseDon't open browser automatically
--themestring"github"Chroma highlight theme
--pdfstring""Export to PDF file and exit (requires Chrome or Chromium)
--htmlstring""Export to HTML file and exit
--versionboolfalsePrint version and exit

Examples

# Open README.md in browser with live reload
mdv README.md

# Use a custom port and dark highlight theme
mdv --port 8080 --theme monokai README.md

# Print URL but don't open browser
mdv --no-browser README.md

# Export to PDF (requires Chrome or Chromium)
mdv --pdf output.pdf README.md

# Export to HTML
mdv --html output.html README.md

# Render Mermaid diagrams in fenced mermaid blocks
mdv diagrams.md

Example Mermaid block:

```mermaid
flowchart TD
  Start --> Ship
```

HTTP Routes

RouteDescription
GET /Redirects to /<filename>.md
GET /<file>.mdFull HTML page (template + rendered markdown)
GET /content?path=/<file>.mdHTML fragment only (for SSE partial refresh)
GET /eventsSSE stream for live reload
GET /<asset>Static files from the Markdown file directory

Architecture

cmd/mdv/main.go            — CLI flag parsing, resolvePort, openBrowser, wiring
internal/mdv/server.go     — HTTP routes: GET /, GET /content, GET /events (SSE)
internal/mdv/renderer.go   — goldmark setup with GFM, Chroma highlighting, Mermaid block handling
internal/mdv/hub.go        — SSE broadcast hub (Register/Unregister/Broadcast)
internal/mdv/watcher.go    — fsnotify file watcher → hub.Broadcast()
internal/mdv/template.go   — Full HTML page template (inline CSS + SSE JS, Mermaid loader)
internal/mdv/pdf.go        — Headless Chrome PDF export (findChrome, PrintToPDF, WaitForServer)
internal/mdv/html.go       — HTML export (ExportHTML)

Data flow:

fsnotify event → WatchFile() → hub.Broadcast()

                         SSE clients (/events) receive "reload"

                    Browser fetches /content → swaps #content innerHTML

Chroma Themes

Common themes: github, github-dark, monokai, dracula, solarized-dark, vs, xcode.

Full list: https://xyproto.github.io/splash/docs/

Why not grip or glow?

mdvgripglow
RenderingLocal (goldmark)GitHub APILocal
Live reloadYes — partial, scroll-preservingNoNo
Syntax highlightingServer-side (Chroma)GitHub APITerminal colors
Mermaid diagramsYesDepends on GitHubNo
PDF exportYes (headless Chrome)NoNo
HTML exportYesNoNo
OutputBrowserBrowserTerminal
OfflineYesNo (needs API)Yes
Rate limitsNoneGitHub API limitsNone

grip sends your Markdown to the GitHub API for rendering — requires a token for heavy use and doesn't work offline. glow renders in the terminal, which is great for quick reads but loses fidelity for complex tables, images, and diagrams. mdv renders locally in your browser with GitHub-style CSS, live reload as you edit, and zero external API calls.