Skip to content

pders01/mdv

Repository files navigation

mdv

A terminal markdown viewer with vim keybindings, built with OpenTUI and shiki for syntax highlighting.

Requirements

  • Bun v1.0 or later

Installation

From GitHub Releases (recommended)

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/mdv

From source

git 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-global

Run without installing

bun run src/index.ts README.md

Usage

# 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-themes

Directory Browsing

Pass a directory instead of a file to open a sidebar file browser:

mdv ./docs

This 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).

Serve Mode

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 ./docs

Default 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.

Live reload

Pass --watch and the page refreshes whenever a markdown file in the served tree changes (creates and renames included):

mdv serve ./docs --watch

Scroll 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.

Mermaid diagrams

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 options

    --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

Keybindings

The same vim-style keymap drives the TUI and the web UI; tables below apply to both unless noted.

Navigation

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

Directory Mode

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.

Yank (Copy)

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

Search

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).

General

Key Action
q / Ctrl-c Quit

Features

  • 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 --watch in 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

Options

-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.

Development

# Run with hot reload
bun dev

# Run directly
bun run src/index.ts <file.md>

Built With

  • OpenTUI - Terminal UI framework
  • shiki - Syntax highlighting
  • marked - Markdown parsing
  • Bun - JavaScript runtime

License

MIT

About

A terminal markdown viewer with vim keybindings.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors