mdpager
v1.0.0
Published
Read markdown files in the terminal with a proper TUI pager
Maintainers
Readme
mdr
Read markdown in your terminal, properly rendered.
mdr README.md opens the file full-screen with headings, syntax-highlighted
code, box-drawn tables, and task lists — then lets you scroll it, search it, jump
around by heading, and follow links to other files. It is a pager, not a cat
with colors.
npm install -g mdpager
mdr README.mdOr without installing:
npx mdpager README.mdUsage
mdr [file]With no argument, mdr opens README.md from the current directory.
mdr # README.md in cwd
mdr docs/guide.md # a specific file
mdr CHANGELOG.md --plain # print to stdout instead of opening the pager
mdr notes.md --watch # reload when the file changes on disk
mdr README.md | less -R # piping switches to plain output automaticallyKeys
| Key | Action |
|:----|:-------|
| j k ↓ ↑ | scroll one line |
| Space b | scroll one page |
| d u | scroll half a page |
| g G | jump to start / end |
| mouse wheel | scroll |
| / | search — Enter to run, Esc to cancel |
| n N | next / previous match |
| t | table of contents — ↑↓ to pick, Enter to jump |
| Tab Shift-Tab | move between links |
| Enter | follow the focused link |
| H L | history back / forward |
| r | reload the file |
| R | toggle live reload |
| m | render the nearest mermaid diagram |
| ? | show all keys |
| q Ctrl-C | quit |
Links to .md files open inside mdr with browser-style history. http links
open in your system browser. #anchor links jump to the matching heading.
Options
| Flag | Default | What it does |
|:-----|:--------|:-------------|
| --plain | auto | Write to stdout without the pager. Automatic when output is piped. |
| --width <n> | terminal width | Force the render width. |
| --theme <name> | auto | dark, light, or auto (guesses from COLORFGBG). |
| --images <auto\|off> | auto | Draw images inline where the terminal supports it. |
| --mermaid <off\|remote> | off | Render mermaid diagrams. See below. |
| --watch | off | Reload automatically when the file changes. |
| --no-color | off | Disable colors. NO_COLOR is honored too. |
| -h, --help | | Show help. |
| -v, --version | | Show version. |
Configuration
Optional, at ~/.config/mdr/config.json. Command-line flags win over the file.
{
"theme": "dark",
"width": 100,
"images": "auto",
"mermaid": "off",
"watch": false
}An unreadable or malformed config file is ignored with a warning — it never stops
mdr from opening your document.
Images
Images are drawn as real pixels in terminals that support a graphics protocol:
- iTerm2 and WezTerm — via the iTerm2 inline image protocol
- Kitty and Ghostty — via the Kitty graphics protocol
Everywhere else — including macOS Terminal.app and GNOME Terminal — images appear as a labeled placeholder showing the alt text and path. Nothing is downloaded; only local image files are read.
Mermaid diagrams
Mermaid blocks are shown as highlighted source by default. Pressing m renders
the nearest diagram as an image, but only when you have opted in:
mdr architecture.md --mermaid=remoteThis sends the diagram source to mermaid.ink, a third-party service, which
returns the rendered PNG. That is why it is off by default and must be enabled
explicitly. Rendering also needs a terminal with graphics support (see above).
There is no offline rendering mode: rendering mermaid locally requires a headless browser, which would add hundreds of megabytes to a global CLI install.
What is supported
Headings, paragraphs, emphasis, nested lists, ordered lists, blockquotes
(including nested), horizontal rules, inline code, and fenced code blocks with
syntax highlighting for any language shiki knows.
From GitHub Flavored Markdown: tables with column alignment, task lists, strikethrough, footnotes, and autolinks.
Text is re-wrapped to your terminal width, so a document written at 120 columns still reads well at 60. CJK characters and emoji are measured at their real display width, so tables and boxes stay aligned.
Development
npm install
npm test # unit, snapshot, and CLI integration tests
npm run typecheck
npm run build
npm run dev -- README.mdThe code is split into three layers with a rule enforced by a test: core/ turns
markdown into styled lines and never touches the terminal, view/ computes what
is visible, and shell/ owns all terminal I/O. Keyboard behavior lives in a
single reducer that returns a new state plus a list of declarative effects, which
is what makes it testable without a pseudo-terminal.
License
MIT
