mdviewer ๐
December 13, 2025 ยท View on GitHub
A beautiful, cross-platform terminal markdown viewer with Mermaid diagram support, built in Go.
Features
Core Rendering
- โจ Beautiful ANSI rendering - Styled markdown output in your terminal with syntax highlighting
- ๐จ Multiple themes - Auto-detect, dark, light, or custom styles (including clean style without hash prefixes)
- ๐ Smart word wrapping - Auto-detects terminal width for optimal display
- ๐ Fast and lightweight - Single binary with embedded dependencies
Images & Diagrams
- ๐ Local Mermaid rendering - Renders diagrams locally using chromedp (no internet required!)
- ๐ผ๏ธ Inline image display - Shows images directly in supported terminals (Warp, iTerm2, Kitty, Windows Terminal, VSCode, WezTerm)
- ๐ Smart image resizing - Bilinear interpolation with aspect ratio preservation
- ๐ฏ Multiple rendering modes - Terminal, SVG export, PNG export, or URL fallback for diagrams
- ๐พ Memory-efficient - Terminal mode works in-memory by default; save to disk only when needed
Obsidian Integration
- ๐ Wiki-link support - Converts
[[page]]and[[page|label]]to standard markdown links - ๐ผ๏ธ Image embeds - Supports
![[image.png]]syntax with automatic path resolution - ๐ Sizing syntax -
![[image.png|400]]resizes images to specified width - ๐ Smart path resolution - Relative paths resolved from markdown file directory
Advanced Features
- ๐ Stdin support - Pipe markdown content from any source
- ๐จ๏ธ PDF export - Export markdown with fully rendered diagrams and images to PDF
- ๐ช Cross-platform - Works seamlessly on macOS, Linux, and Windows
- ๐ญ Protocol auto-detection - Automatically detects and uses appropriate terminal image protocols
- ๐ Neovim integration - Full-featured plugin for in-editor live preview (
contrib/neovim/mdviewer.nvim)
Installation
Prebuilt binaries (recommended)
You can download ready-to-use binaries from the GitHub Releases page:
-
Binaries are built automatically by GitHub Actions for each tag starting with
v(for example:v1.0.0). -
Supported platforms:
- macOS (Intel, Apple Silicon)
- Linux (AMD64, ARM64)
- Windows (AMD64)
-
Each release includes compressed archives:
mdviewer-darwin-amd64.tar.gzmdviewer-darwin-arm64.tar.gzmdviewer-linux-amd64.tar.gzmdviewer-linux-arm64.tar.gzmdviewer-windows-amd64.zip
-
Each release also includes a
checksums.txtfile with SHA-256 hashes for all archives and binaries.
To download and install:
- Open the Releases page: https://github.com/aquele-dinho/mdviewer/releases
- Pick the desired version (tag
vX.Y.Z). - Download the archive matching your OS/architecture.
- (Optional) Verify the SHA-256 checksum using
checksums.txt. - Extract the archive:
- macOS/Linux (
.tar.gz):tar -xzf mdviewer-<platform>.tar.gz - Windows (
.zip): use File Explorer orExpand-Archivein PowerShell.
- macOS/Linux (
- On Unix-like systems, make the binary executable if needed:
chmod +x mdviewer-*. - Run
./mdviewer --helpor./mdviewer --versionto verify it works.
Make mdviewer available system-wide
macOS & Linux
- Move the binary into a directory on your
PATH(for example/usr/local/binor~/.local/bin):sudo mv mdviewer-* /usr/local/bin/mdviewer # or, without sudo if you use ~/.local/bin mkdir -p ~/.local/bin mv mdviewer-* ~/.local/bin/mdviewer - Ensure the directory is on your
PATH(for~/.local/bin, add this to your shell config like~/.zshrcor~/.bashrc):export PATH="$HOME/.local/bin:$PATH" - Restart your shell or source your config file, then run:
mdviewer --version
Windows (PowerShell)
- Extract
mdviewer-windows-amd64.zipand rename the binary if you like (for examplemdviewer.exe). - Move it into a directory on your
PATH(for exampleC:\\Users\\<you>\\bin):New-Item -ItemType Directory -Force "$env:USERPROFILE\bin" | Out-Null Move-Item ".\mdviewer-windows-amd64.exe" "$env:USERPROFILE\bin\mdviewer.exe" - Add that directory to your user
PATH(Windows Settings โ System โ About โ Advanced system settings โ Environment Variables), or from PowerShell:[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$env:USERPROFILE\bin", "User") - Open a new terminal and run:
mdviewer --version
From Source
go install github.com/aquele_dinho/mdviewer/cmd/mdviewer@latest
Build Locally
git clone https://github.com/aquele_dinho/mdviewer.git
cd mdviewer
go build -o mdviewer ./cmd/mdviewer
Usage
Basic Usage
# View a markdown file
mdviewer README.md
# Read from stdin
cat document.md | mdviewer
echo "# Hello World" | mdviewer
# Use with less for scrolling
mdviewer large-doc.md | less -R
Options
# Use dark theme
mdviewer document.md --style dark
# Use light theme
mdviewer document.md --style light
# Use clean style (no hash prefixes on headings)
mdviewer document.md --style clean
# Custom terminal width
mdviewer document.md --width 100
# Disable mermaid detection
mdviewer document.md --no-mermaid
# Mermaid rendering modes
mdviewer document.md --mermaid-mode=terminal # Default: Memory-only (inline or ASCII preview)
mdviewer document.md --mermaid-mode=svg # Export SVGs to temp directory
mdviewer document.md --mermaid-mode=png # Export PNGs to temp directory
mdviewer document.md --mermaid-mode=url # Show URLs + code (no local rendering)
# Save Mermaid diagrams to disk (terminal mode only)
mdviewer document.md --keep-mermaid-files # Saves SVG files to temp directory
mdviewer document.md -k --mermaid-output-dir=./diagrams # Save to custom directory
# Export to PDF
mdviewer document.md --export-pdf output.pdf
Help
mdviewer --help
mdviewer --version
Supported Markdown Features
- Headings (H1-H6)
- Bold, Italic,
Code - Lists (ordered and unordered)
- Tables
- Blockquotes
- Code blocks with syntax highlighting
- Links (standard markdown and Obsidian wiki-links)
- Images with inline display and resizing support
- Horizontal rules
- Mermaid diagrams (rendered inline or exported)
Mermaid Diagram Support
mdviewer now renders Mermaid diagrams locally using headless Chrome (chromedp). No internet connection required!
Security note: for PDF export and local Mermaid rendering, mdviewer allows raw HTML from your markdown (via Goldmark's
WithUnsafeoption). This is intended for local workflows where you trust the content. Be cautious when rendering untrusted markdown, as it may include arbitrary HTML that headless Chrome will process.
```mermaid
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[End]
B -->|No| D[Continue]
\```
Rendering Modes
Terminal Mode (Default)
Displays diagrams inline (if your terminal supports it) or as an ASCII preview box. Files are kept in memory by default - no disk files are created unless you use --keep-mermaid-files:
Inline Image Support (auto-detected):
- โ Warp Terminal (iTerm2 protocol)
- โ iTerm2 on macOS (iTerm2 protocol)
- โ Kitty terminal (Kitty graphics protocol)
- โ Windows Terminal v1.22+ (Sixel/iTerm2 protocol)
- โ VSCode integrated terminal (iTerm2 protocol)
- โ WezTerm (multiple protocols)
If your terminal supports inline images, diagrams will render directly in the output:
๐ Mermaid Diagram (Flowchart):
[actual rendered image appears here]
Otherwise, you'll see an ASCII info box:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ Mermaid Diagram: Flowchart โ
โ ๐ Dimensions: 232x334 px โ
โ โ
Rendered locally โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
To save diagrams to disk, use the --keep-mermaid-files flag:
mdviewer doc.md --keep-mermaid-files
# Files saved to system temp directory by default
mdviewer doc.md -k --mermaid-output-dir=./my-diagrams
# Files saved to custom directory
SVG Mode
Exports SVG files to disk (no terminal preview):
mdviewer doc.md --mermaid-mode=svg
# Files saved to system temp directory
mdviewer doc.md --mermaid-mode=svg --mermaid-output-dir=./diagrams
# Files saved to custom directory
PNG Mode
Exports diagrams as PNG images to disk:
mdviewer doc.md --mermaid-mode=png
# Files saved to system temp directory
mdviewer doc.md --mermaid-mode=png --mermaid-output-dir=./diagrams
# Files saved to custom directory
URL Mode (Fallback)
Shows the mermaid code + clickable URLs to mermaid.live and mermaid.ink:
mdviewer doc.md --mermaid-mode=url
Supported Mermaid Diagram Types
- Flowcharts
- Sequence Diagrams
- Class Diagrams
- State Diagrams
- ER Diagrams
- Gantt Charts
- Pie Charts
- Git Graphs
- User Journey Maps
Inline Image Support
mdviewer displays images directly in supported terminals using inline image protocols with advanced rendering capabilities.
Standard Markdown Syntax


Obsidian-Style Syntax
Full support for Obsidian's wiki-style syntax with intelligent preprocessing:
# Basic image embed
![[image.png]]
# With width specification (resizes to 400px width, maintains aspect ratio)
![[image.png|400]]
![[photo.jpg|800]] # Supports upscaling with bilinear interpolation
# Wiki-links for pages
[[other-page]] # Converts to: [other-page](./other-page.md)
[[page|Custom Label]] # Converts to: [Custom Label](./page.md)
[[docs/setup]] # Converts to: [docs/setup](./docs/setup.md)
How It Works
- Preprocessing: Obsidian syntax is converted to standard markdown before rendering
- Content Detection: Unified block detection identifies all images and mermaid diagrams
- Segmented Rendering: Content is rendered in document order, maintaining structure
- Smart Resizing: Width specifications trigger bilinear interpolation for high-quality scaling
Supported Image Formats
- PNG (
.png) - Preferred for lossless quality after resizing - JPEG (
.jpg,.jpeg) - Automatically converted to PNG when resized - GIF (
.gif) - Static GIF support - WebP (
.webp) - Modern format support
Image Display Behavior
Terminals with inline image support:
- โ Images display directly in terminal output using appropriate protocol (iTerm2, Kitty, Sixel)
- โ Automatic bilinear interpolation resizing when width specified
- โ Aspect ratio always maintained
- โ Supports both downscaling and upscaling
- โ Images and Mermaid diagrams render in document order
Terminals without inline image support:
- โน๏ธ Falls back to descriptive text representation
- โน๏ธ Shows file path for reference
- โน๏ธ Indicates image format and alt text
Path Resolution:
- โ
Relative paths (e.g.,
./images/photo.png) are resolved from the markdown file's directory - โ Absolute paths work as-is
- โ
Obsidian-style bare paths (e.g.,
![[photo.png]]) are normalized to relative paths - โ HTTP/HTTPS URLs are not displayed inline (shown as text links only)
Image Resizing Technical Details
Resize Algorithm:
- Uses
golang.org/x/image/drawwith bilinear interpolation - High-quality scaling in both directions (up and down)
- Maintains aspect ratio automatically
Performance:
- Original image cached in memory during resize
- Resized images encoded to PNG for lossless quality
- Only processes images when width specification is present
Example:
![[large-image.png|400]] # Original: 2000x1500px โ Resized: 400x300px
![[small-icon.png|200]] # Original: 50x50px โ Upscaled: 200x200px
Examples
# View markdown with images
mdviewer document.md
# Images will display inline in Warp, iTerm2, Kitty, etc.
# Other terminals will show text placeholders
Neovim Plugin
mdviewer includes a full-featured Neovim plugin for in-editor markdown preview. Preview your markdown files in a split or floating terminal window with live auto-refresh.
Features
- โ Live preview - Auto-refreshes as you edit (configurable debounce)
- โ Flexible layout - Vertical split, horizontal split, or floating window
- โ Full mdviewer support - All features including Mermaid diagrams and inline images
- โ Path resolution - Relative paths work correctly (preview runs in file's directory)
- โ Easy setup - Works with lazy.nvim, packer, or native packages
Quick Start
- Install the plugin (using lazy.nvim):
{
dir = '/path/to/mdviewer/contrib/neovim/mdviewer.nvim',
ft = 'markdown',
opts = {
style = 'clean',
window_type = 'vsplit', -- 'vsplit' | 'hsplit' | 'float'
auto_refresh = true,
mermaid_mode = 'terminal',
},
}
- Use in Neovim:
:MDViewerToggle " Toggle preview on/off
:MDViewerRefresh " Force refresh
:MDViewerClose " Close preview
- Optional keymap:
vim.keymap.set('n', '<leader>mp', '<cmd>MDViewerToggle<cr>',
{ desc = 'mdviewer: toggle preview' })
Full Documentation
See the complete installation and configuration guide:
- Plugin README:
contrib/neovim/mdviewer.nvim/README.md - Includes setup for lazy.nvim, packer, and native packages
- Configuration options for styling, window type, auto-refresh, etc.
Configuration
mdviewer uses Glamour for rendering. You can customize the appearance by:
- Using built-in styles:
auto,dark,light,clean(no hash prefixes) - Providing a path to a custom Glamour style JSON file
Style Comparison
- auto/dark/light: Traditional styles that show
##and###prefixes on H2/H3 headings - clean: Modern style without hash prefixes, similar to GUI markdown viewers
Examples
View this README
mdviewer README.md
Pipe content
curl https://raw.githubusercontent.com/username/repo/main/README.md | mdviewer
Custom theme
mdviewer document.md --style /path/to/custom-style.json
Project Structure
mdviewer/
โโโ cmd/
โ โโโ mdviewer/ # CLI entry point (Cobra-based)
โ โโโ main.go # Command-line interface and flags
โโโ internal/
โ โโโ mermaid/ # Local Mermaid compiler (chromedp)
โ โ โโโ assets/ # Embedded mermaid.min.js
โ โ โโโ compiler.go # Chromedp-based renderer
โ โ โโโ svg.go # SVG utilities and dimension extraction
โ โ โโโ embed.go # go:embed for mermaid.js
โ โโโ renderer/ # Markdown rendering engine
โ โ โโโ markdown.go # Main ANSI renderer (Glamour)
โ โ โโโ html.go # HTML renderer (Goldmark, for PDF)
โ โ โโโ mermaid.go # Mermaid block detection
โ โ โโโ images.go # Image block detection
โ โ โโโ blocks.go # Unified content block management
โ โ โโโ links.go # Obsidian wiki-link preprocessing
โ โ โโโ styles.go # Custom style definitions
โ โโโ viewer/ # Display logic and segmented rendering
โ โ โโโ simple.go # Terminal viewer with inline image support
โ โโโ pdf/ # PDF export with chromedp
โ โ โโโ exporter.go # High-level export interface
โ โ โโโ chromedp.go # Low-level PDF generation
โ โโโ utils/ # Utilities and helpers
โ โโโ terminal.go # Terminal width detection
โ โโโ termimg.go # Inline image protocol support
โ โโโ resize.go # Image resizing with bilinear interpolation
โ โโโ file.go # File I/O utilities
โ โโโ browser.go # Browser launch utilities
โโโ .github/
โ โโโ workflows/
โ โโโ release.yml # Automated multi-platform builds
โโโ go.mod # Go module dependencies
โโโ go.sum # Dependency checksums
โโโ build.sh # Local build script
โโโ CHANGELOG.md # Version history
โโโ WARP.md # Development guide for AI assistants
โโโ README.md # This file
Architecture Overview
Content Processing Pipeline:
1. Input (file/stdin)
โ
2. Obsidian Link Preprocessing (links.go)
- Converts [[page]] โ [page](./page.md)
- Converts ![[image.png|400]] โ 
โ
3. Content Block Detection (blocks.go)
- Detects all Mermaid diagrams (mermaid.go)
- Detects all images (images.go)
- Sorts by document order
โ
4. Segmented Rendering (viewer/simple.go)
- Renders markdown segments between special blocks
- Processes Mermaid diagrams (via mermaid/compiler.go)
- Processes images with resizing (via utils/resize.go)
- Displays inline or exports to files
โ
5. Output (terminal or PDF)
Key Design Decisions:
- Fresh chromedp contexts: Each Mermaid render creates a new context to prevent memory leaks
- Memory-first approach: Terminal mode works entirely in-memory unless
--keep-mermaid-filesis used - Unified block detection: Single pass identifies all special content (images + mermaid) for ordered rendering
- Preprocessing before detection: Obsidian syntax converted early to simplify downstream processing
- Bilinear interpolation: High-quality image scaling using
golang.org/x/image/draw
Development
Release process (maintainers)
Releases are automated via GitHub Actions using the workflow in .github/workflows/release.yml.
- Ensure the default branch (usually
main) is in the desired state. - Create and push a version tag:
git tag vX.Y.Z git push origin vX.Y.Z - GitHub Actions will:
- Build
mdviewerbinaries for all supported platforms - Generate
dist/checksums.txtwith SHA-256 hashes - Create a GitHub Release for the tag and upload the binaries and checksums
- Build
- Share the Release page URL with users so they can download the binaries.
The mdviewer --version output corresponds to the tag version (without the leading v).
Prerequisites
- Go 1.21 or higher
Building
go build -o mdviewer ./cmd/mdviewer
Testing
go test ./...
Roadmap
Completed โ
-
Core Rendering
- Basic markdown rendering with Glamour
- Multiple color themes (auto, dark, light, clean)
- Terminal width auto-detection
- Stdin support for piping
-
Mermaid Diagrams
- Mermaid diagram detection
- Local Mermaid rendering (chromedp)
- Multiple rendering modes (terminal, SVG, PNG, URL)
- Memory-efficient terminal mode
- Optional disk export with
--keep-mermaid-files
-
Images
- Terminal inline image support (iTerm2, Kitty, Warp, Windows Terminal, VSCode, WezTerm)
- Obsidian-style syntax support (wiki-links, image embeds)
- Image resizing with bilinear interpolation
- Aspect ratio preservation
- Multiple format support (PNG, JPEG, GIF, WebP)
- Smart path resolution
-
Export
- PDF export with chromedp
- SVG export for diagrams
- PNG export for diagrams
-
Architecture
- Unified content block detection
- Segmented rendering in document order
- Obsidian link preprocessing
- Cross-platform support (macOS, Linux, Windows)
- Automated multi-platform builds via GitHub Actions
-
Editor Integration
- Neovim plugin for in-editor preview (
contrib/neovim/mdviewer.nvim)
- Neovim plugin for in-editor preview (
Planned ๐ฏ
-
Interactive Features
- Interactive TUI mode with Bubbletea
- Search functionality
- Link navigation (follow links within documents)
- Keyboard shortcuts for common actions
-
Live Editing
- Watch mode for live markdown updates
- Auto-reload on file changes
- Side-by-side preview mode
-
Customization
- Custom style editor/creator
- Theme marketplace or gallery
- Configuration file support (
.mdviewerrc) - Backlinks support
- Tag navigation
- Graph view for linked notes
- Transclusion support
-
Performance & Optimization
- Caching for rendered Mermaid diagrams
- Parallel rendering for multiple diagrams
- Incremental rendering for large documents
Under Consideration ๐ญ
- Additional Editor Integrations
- VSCode extension integration
- Emacs mode
- Vim plugin (classic Vim)
- Advanced Rendering
- Math equation rendering (KaTeX/MathJax)
- Network diagram rendering (beyond Mermaid)
- Notebook format support (Jupyter, Observable)
- Export & Presentation
- Presentation mode (slides from markdown)
- Export to more formats (DOCX, EPUB)
- Extensibility
- Custom plugin system
- API for external integrations
Technologies
Core Libraries
- Glamour - Terminal markdown rendering with ANSI styling
- Cobra - CLI framework for command-line interface
- Goldmark - Markdown parser for HTML generation (PDF export)
- Chromedp - Headless Chrome automation for Mermaid rendering and PDF export
Image Processing
- golang.org/x/image/draw - High-quality image scaling with bilinear interpolation
- Standard library (
image,image/png,image/jpeg,image/gif) - Image decoding and encoding
Terminal Protocols
- iTerm2 inline images protocol - Base64-encoded images with escape sequences
- Kitty graphics protocol - Terminal-native image display
- Sixel graphics - Legacy but widely supported protocol
Build & Release
- GitHub Actions - Automated multi-platform builds and releases
- Go build system - Cross-compilation for macOS, Linux, and Windows
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License
Author
Built with โค๏ธ by @aquele_dinho
Acknowledgments
- The Charm team for Glamour and Bubbletea
- The Go community for excellent libraries