A terminal markdown viewer with vim keybindings, built with OpenTUI and shiki for syntax highlighting.
- Bun v1.0 or later
Download the latest binary for your platform from Releases:
# macOS (Apple Silicon)
curl -LO https://github.com/pders01/mdv/releases/latest/download/mdv-darwin-arm64.tar.gz
tar xzf mdv-darwin-arm64.tar.gz && sudo mv mdv-darwin-arm64 /usr/local/bin/mdv
# macOS (Intel)
curl -LO https://github.com/pders01/mdv/releases/latest/download/mdv-darwin-x64.tar.gz
tar xzf mdv-darwin-x64.tar.gz && sudo mv mdv-darwin-x64 /usr/local/bin/mdv
# Linux (x64)
curl -LO https://github.com/pders01/mdv/releases/latest/download/mdv-linux-x64.tar.gz
tar xzf mdv-linux-x64.tar.gz && sudo mv mdv-linux-x64 /usr/local/bin/mdvgit clone https://github.com/pders01/mdv.git
cd mdv
bun install
# Build for current platform
bun run build
sudo mv mdv /usr/local/bin/
# Or use the install script
bun run install-globalbun run src/index.ts README.md# View a markdown file
mdv README.md
# Browse a directory of markdown files
mdv ./docs
mdv .
# Read from stdin (pipe)
cat README.md | mdv
curl -s https://example.com/doc.md | mdv
# Watch a file for live reload
mdv -w README.md
# Watch a directory (reloads active file, marks changed files in sidebar)
mdv -w ./docs
# Serve a directory over HTTP with the same vim keymap on the web
mdv serve ./docs
# Serve with live reload — page refreshes on every save
mdv serve ./docs --watch
# With a specific theme
mdv -t dracula README.md
# Exclude directories when browsing
mdv -e drafts -e tmp ./docs
# List available themes
mdv --list-themesPass a directory instead of a file to open a sidebar file browser:
mdv ./docsThis recursively scans for .md files and displays them in a navigable sidebar. The following directories are excluded by default: node_modules, .git, vendor, dist, build, .next, .nuxt, __pycache__, .venv, target, .hg, .svn.
Use -e/--exclude to add custom exclusions (repeatable).
Use mdv serve to serve a directory of markdown files over HTTP. The web UI mirrors the TUI's two-pane layout and vim keymap, so muscle memory carries between modes:
mdv serve ./docsDefault URL is http://localhost:4280. The same Shiki theme drives both modes — mdv serve --theme dracula recolors the entire web UI from a single CSS-variable block.
Pass --watch and the page refreshes whenever a markdown file in the served tree changes (creates and renames included):
mdv serve ./docs --watchScroll position, sidebar cursor, and pane focus are preserved across reloads via sessionStorage, so saving a file lands you back at the same place — no manual re-scrolling.
Fenced ```mermaid blocks render client-side from a locally-vendored mermaid bundle. The bundle is lazy-loaded only when a page actually contains a mermaid fence, so docs without diagrams pay zero bytes. Pass --no-mermaid to skip it; fences then render as plain code blocks.
--serve Serve over HTTP instead of TUI (or use the `serve` subcommand)
-p, --port <port> Port to bind (default: 4280)
--host <host> Host to bind (default: localhost)
-o, --open Open the URL in the default browser
-q, --quiet Suppress startup banner and access log
-w, --watch Live reload on file changes
--no-mermaid Skip the mermaid adapter
The same vim-style keymap drives the TUI and the web UI; tables below apply to both unless noted.
| Key | Action |
|---|---|
j / ↓ |
Scroll down one line |
k / ↑ |
Scroll up one line |
gg |
Go to top |
G |
Go to bottom |
Ctrl-d |
Scroll down half page |
Ctrl-u |
Scroll up half page |
Ctrl-f / Space / PageDown |
Scroll down full page |
Ctrl-b / PageUp |
Scroll up full page |
Home |
Go to top |
End |
Go to bottom |
| Key | Action |
|---|---|
Tab |
Switch panes |
Ctrl-h |
Focus sidebar |
Ctrl-l |
Focus reader |
\ |
Toggle sidebar |
Enter |
Open file from sidebar |
Esc |
Back to reader pane |
All navigation keys (j/k, Ctrl-d/u, etc.) work in both panes.
| Key | Action |
|---|---|
yy |
Copy entire document to clipboard |
V |
Enter visual line mode |
y (in visual mode) |
Copy selection to clipboard |
Esc |
Exit visual mode |
| Key | Action |
|---|---|
/ |
Start search |
n |
Next match |
N |
Previous match |
Esc |
Clear search / cancel input |
Search works in both the reader pane and the sidebar file list. Matches are highlighted inline with exact position awareness (accounts for markdown conceal).
| Key | Action |
|---|---|
q / Ctrl-c |
Quit |
- Full markdown rendering with proper styling
- Syntax highlighting for code blocks (50+ languages)
- Theme support via shiki (github-dark default, 30+ themes available)
- Two viewing modes from one binary: TUI (default) and HTTP (
mdv serve) - Live reload with
--watchin both modes; the web mode preserves scroll and cursor across reloads - Directory browsing with sidebar file tree
- Pager-style search (
/,n/N) with inline match highlighting (works against the active pane in both modes) - Vim-style navigation shared between the TUI and the web UI
- Mermaid diagrams rendered as ASCII in the TUI and SVG client-side on the web (locally bundled, no CDN)
- Supports:
- Headings (ATX and Setext style)
- Bold, italic, strikethrough
- Links (with URL display)
- Images (shows alt text)
- Code blocks with syntax highlighting
- Inline code
- Ordered and unordered lists (nested)
- Blockquotes (nested)
- Tables
- Horizontal rules
- HTML blocks and inline HTML
- Subscript/superscript (via Unicode)
- Reference-style links
- Escape sequences
-t, --theme <name> Set syntax highlighting theme (default: github-dark)
-T, --list-themes List available themes
-w, --watch Live reload on file changes
-e, --exclude <dir> Exclude directory from scan (repeatable)
--no-mouse Disable mouse input (TUI only)
--no-mermaid Disable mermaid diagram rendering
--serve Serve over HTTP instead of TUI
-p, --port <port> Port for serve mode (default: 4280)
--host <host> Host for serve mode (default: localhost)
-o, --open Open the served URL in the default browser
-q, --quiet Suppress startup banner and access log (serve mode)
--debug Enable debug logging
-v, --version Show version
-h, --help Show help
Run mdv --help for the same list grouped by section.
# Run with hot reload
bun dev
# Run directly
bun run src/index.ts <file.md>- OpenTUI - Terminal UI framework
- shiki - Syntax highlighting
- marked - Markdown parsing
- Bun - JavaScript runtime
MIT