mdp — instant markdown preview in your browser

Preview any .md file in a real browser tab — single static binary. Pairs with md-preview.nvim for live scroll-sync (the editor cursor tracks the rendered page).
https://github.com/user-attachments/assets/19f64fa1-a4d6-4a9c-a94f-2c40ca5a979b
Install
[!NOTE]
Linux and macOS only (amd64 / arm64). Windows is not supported.
One-liner — uses go install if Go is on PATH, otherwise downloads a prebuilt release tarball:
curl -fsSL https://raw.githubusercontent.com/aldevv/md-preview/main/install.sh | sh
System-wide (default prefix is $HOME/.local):
curl -fsSL https://raw.githubusercontent.com/aldevv/md-preview/main/install.sh | PREFIX=/usr/local sh
Or directly with Go:
go install github.com/aldevv/md-preview/cmd/mdp@latest
- Prebuilt binaries — Releases page.
- Building from source needs Go 1.26.2+ (release users don't).
Verify the install:
mdp help
Update to the latest release in place (uses go install if Go is on PATH, otherwise downloads the matching release tarball and swaps the binary):
mdp update # install latest
mdp update --check # just report whether an update is available
mdp auto-detects a browser (Chromium- or Firefox-family, then xdg-open / open). Override via browser = ... in the config.
Optional: fzf
fzf is the fuzzy-finder used by the no-arg picker mode — mdp with no file argument fzf-picks a .md from the current directory. If fzf is missing, the help text is printed instead.
Usage
mdp README.md # render + open in browser
mdp # fzf-pick a .md from cwd, then preview
mdp watch README.md # auto-refresh when the file changes (any editor)
mdp -e README.md # preview AND open the file in nvim
mdp -e # fzf-pick, preview, and edit
mdp -t light README.md # light theme
mdp -p README.md # print HTML path, don't open browser
mdp serve README.md 8080 dark # plugin server mode (used by md-preview.nvim)
mdp help # show help
mdp watch keeps mdp running and the browser refreshes whenever the file
is saved — editor-agnostic (works with VS Code, Sublime, vim, Helix, your
$EDITOR, anything that writes to disk). Ctrl-C to stop; the preview tab
closes with it (chrome --app= mode) or shows a "server stopped" notice.
Keys
| Action |
Default |
Colemak |
| Down / Up |
j / k |
n / e |
| Left / Right |
h / l |
h / i |
| Half-page down/up |
d / u |
d / u |
| Top / Bottom |
g / G |
g / G |
| Close |
q |
q |
Enable Colemak with colemak = true in the config.
Notes
The default preview is static — re-run mdp to refresh, use mdp watch for
auto-refresh on save (any editor), or install the
Neovim plugin for live scroll-sync.
YAML frontmatter is stripped.
[!IMPORTANT]
Raw HTML in markdown is intentionally not rendered: the preview origin is loopback-bound and a malicious README could otherwise inject scripts.
Config
Settings live in ~/.config/md-preview/config.toml; a commented template is seeded on first run. All keys optional:
theme = "dark" # "dark" or "light"
font_size = 18 # body font-size in px
custom_css = "~/path.css" # appended after defaults; cascade wins
browser = "auto" # "auto" | "firefox --new-window" | ["cmd", "arg"]
# The URL is appended as the last arg.
# auto = chrome --app= → xdg-open / open
edit = false # default for -e (also open nvim). Override with -e / --no-edit.
colemak = false # swap in-page nav keys j/k/l → n/e/i
CLI flags override config values.
Neovim plugin
For live scroll-sync — where the rendered page tracks your editor cursor as you scroll the source — install the sibling plugin:
The plugin spawns mdp serve <file> <port> <theme> as a long-lived loopback HTTP+WebSocket server and drives it over stdin newline-delimited JSON (render, scroll, quit). Plugin authors and contributors: see docs/server.md for the IPC contract, endpoints, and internal layout.
Claude Code skill
If you use Claude Code, there's a companion skill at general/.claude/skills/md-preview (in aldevv/dotfiles) that lets Claude open markdown content in mdp on demand. Trigger it with /md-preview <path> to render a file, or just say "open this in mdp" / "show me the README rendered" and Claude resolves the file or writes generated content to a tempfile, then spawns mdp on it. Per-invocation by design (no auto-trigger). Requires this binary on $PATH.
The skill loads its mdp-driving reference from the binary itself via mdp skill path, so the canonical guide on invocation modes, tempfile conventions, and spawn semantics ships with the release rather than the skill prose.
Contributing
Issues and PRs welcome at github.com/aldevv/md-preview/issues.
make test # go test ./...
make build # produces ./mdp
make install # go install ./cmd/mdp
License
MIT — see LICENSE.