mdcat-ng
Render Markdown in the terminal. Inline images, syntax-highlighted code, hyperlinks, an interactive viewer.
What it is
Project provides two binaries. mdcat renders a Markdown file
to stdout; mdless opens an interactive view over the same output.
Inline images work natively on iTerm2, Kitty, WezTerm, Ghostty,
Rio, VS Code, and Terminology, and via DEC Sixel on Foot,
Contour, mlterm, Windows Terminal (1.22+), and xterm -ti vt340.
When the terminal can't render an image, links fall back to OSC 8
hyperlinks. Fenced code blocks are highlighted with syntect.
mdless renders the document once, pins the bytes in a buffer,
and scrolls in place. Images are disabled during the rendering.
Install
Homebrew (macOS, Linux):
Scoop (Windows):
cargo-binstall (prebuilt binary):
From source:
Building from source needs libcurl: macOS bundles it,
Debian/Ubuntu need libcurl4-dev, Fedora curl-devel.
Prebuilt tarballs for every release: https://github.com/pawelb0/mdcat-ng/releases
mdcat
|
Full flag list: mdcat --help or mdcat(1).
Piped output
When stdout is a pipe, styling and image escapes drop and the
output is plain text — same convention as cat, grep, and ls.
If you want colour through a pipe, pass --ansi or keep LESS=-R
in the environment.
tmux and GNU screen
Set allow-passthrough on in the tmux config and image escapes
reach the underlying terminal. Screen triggers the same DCS wrap
automatically from $STY.
Remote images
HTTP images are not fetched by default. Opt in explicitly:
mdless
Interactive Markdown viewer — vi-style scrolling, live search with highlight, heading jumps, TOC modal, bookmarks.
Keys
| Key | Action |
|---|---|
j / k |
Scroll one rendered line down / up |
Space / b |
Page forward / back |
Ctrl+D / U |
Half page forward / back |
g / G |
Jump to top / bottom |
NG |
Jump to rendered line N (numeric prefix) |
/PATTERN |
Forward search (smart-case, literal by default) |
?PATTERN |
Backward search |
n / N |
Next / previous match |
Esc |
Clear search highlights |
]] / [[ |
Jump to next / previous heading |
T |
Open the TOC modal (Enter jumps, Esc closes) |
m{a-z} |
Save the current top as bookmark a..z |
'{a-z} |
Jump back to a saved bookmark |
Ctrl+L |
Force redraw |
q / Ctrl+C |
Quit |
Flags
| Flag | Purpose |
|---|---|
--search PATTERN |
Commit a query before the event loop starts |
--regex |
Interpret the pattern as a regex |
--case-sensitive |
Disable smart-case; force case-sensitive matching |
--external-pager |
Fall back to $PAGER / less -r |
--no-pager / -P |
Skip the interactive view and print to stdout |
Terminal support
| Terminal | Styling | Hyperlinks | Images | Notes |
|---|---|---|---|---|
| iTerm2 | ✓ | ✓ | native | Heading jump marks (⇧⌘↑ / ⇧⌘↓) |
| Kitty | ✓ | ✓ | native | Kitty graphics protocol |
| WezTerm | ✓ | ✓ | native | Kitty + iTerm2 |
| Ghostty | ✓ | ✓ | native | Kitty protocol |
| Rio | ✓ | ✓ | native | Kitty protocol |
| VS Code | ✓ | ✓ | native | iTerm2 protocol |
| Terminology | ✓ | ✓ | native | tycat protocol |
| Foot | ✓ | ✓ | Sixel | |
| Windows Terminal | ✓ | ✓ | Sixel | Since 1.22 |
| Contour | ✓ | ✓ | Sixel | |
| mlterm | ✓ | Sixel | ||
| xterm | ✓ | Sixel¹ | xterm -ti vt340 |
|
| Alacritty | ✓ | ✓ | ||
| Konsole | ✓ | ✓ | ||
| Warp | ✓ | ✓ | ||
| Hyper | ✓ | |||
| Apple Terminal | ✓ | macOS 15+ | OSC 8 gated on macOS version | |
| Basic ANSI | ✓ | Strikethrough + OSC 8 required |
- Detected at runtime via a Primary Device Attributes probe
unless
--no-probe-terminalis set. If your terminal advertises Sixel but the probe times out, bump the window with--probe-timeout-ms 200.
SVG images render via resvg; its support matrix lists the SVG features that round-trip faithfully.
Markdown extensions
Beyond CommonMark:
- Pipe tables, task lists (
- [x]), strikethrough (~~text~~) - GFM alert blockquotes (
> [!NOTE],> [!TIP],> [!IMPORTANT],> [!WARNING],> [!CAUTION]) - Smart punctuation (curly quotes, en/em dash, ellipsis)
- Footnotes, definition lists, wiki links (
[[Page]],[[Page|label]])
Not supported: math ($inline$, $$block$$), inline markup
inside table cells (plain text only), cell reflow — cells
truncate with ….
Library use
use ;
use Parser;
use SyntaxSet;
let markdown = "# Hello\n\nRendered with **mdcat**.\n";
let settings = Settings ;
let env = for_local_directory?;
let handler = create_resource_handler?;
let mut out = Vecnew;
push_tty?;
Packaging
A cargo install gives you both binaries. Package metadata:
- Manpage:
asciidoctor -b manpage -a reproducible mdcat.1.adoc. Symlinkmdless.1to the same manpage. - Shell completions:
mdcat --completions {bash,zsh,fish}, same formdless.
Troubleshooting
MDCAT_LOG=trace turns on full trace logging; scope it with
MDCAT_LOG=mdcat::render=trace for a single module. Logs go to
stderr.
mdcat --detect-terminal prints the detected terminal, the
multiplexer (if any), and whatever the DA1 probe discovered — the
first thing to check if an image protocol isn't firing where you
expect it to.
Contributing
See CONTRIBUTING.md. The short version is
cargo fmt --check && cargo clippy --all-targets --all-features -- -D warnings && cargo test --all-targets before you open a PR.
Licence
MPL-2.0, with a handful of files dual-licensed Apache-2.0. File headers mark the applicable licence. See LICENSE and the CHANGELOG for release history.
Acknowledgements
Based on swsnr/mdcat.