Markon
A lightweight Markdown renderer with GitHub styling and Medium-like annotation features, written in Rust.

English | 简体中文
Use Cases
Markon makes it easy to read, print, and annotate Markdown files in beautiful HTML format. Whether you're:
- Reading documentation on remote servers without a GUI
- Reviewing and annotating technical documents with highlights and notes
- Printing Markdown files with professional formatting
- Presenting Markdown content with GitHub-style rendering
Simply run markon in any directory to browse and render Markdown files with a clean, distraction-free interface.
Features
Core Features
- ✅ GitHub Styling: Complete GitHub Markdown CSS (dark/light themes)
- ✅ Syntax Highlighting: Powered by Syntect
- ✅ GitHub Alerts: Support for NOTE, TIP, IMPORTANT, WARNING, CAUTION
- ✅ Emoji Support: Unicode emoji shortcodes (e.g.,
:smile:→ 😄) - ✅ Mermaid Diagrams: Flowcharts, sequence diagrams, pie charts, etc.
- ✅ Theme Switching: Light, dark, and auto themes
- ✅ Table Support: GitHub Flavored Markdown (GFM) tables
- ✅ Task Lists: Checkbox task lists
- ✅ Print Optimization: Professional print styles with multilingual font support
- ✅ Table of Contents: Auto-generated TOC
- ✅ Directory Browsing: Auto-list Markdown files in current directory
- ✅ Zero Dependencies: All resources embedded in a single binary
Medium-Style Annotation Features
- ✅ Text Highlighting: Add orange, green, or yellow highlights to selected text
- ✅ Strikethrough: Mark text with strikethrough
- ✅ Notes: Add annotation notes to highlighted text
- ✅ Sidebar Display: Note cards displayed on the right side, linked to highlights
- ✅ Unhighlight: Remove highlights from selected text
- ✅ Persistent Storage: Annotation data saved in browser local storage
Installation
From crates.io
From source
Run directly without installing
Usage
Basic Usage
# Display list of Markdown files in current directory
# Render a specific Markdown file
# Specify port
# Use dark theme
# Use light theme
# Auto theme (based on system settings)
Command Line Options
Usage: markon [OPTIONS] [FILE]
Arguments:
[FILE] The markdown file to render
Options:
-p, --port <PORT> The port to use for the server [default: 6419]
-t, --theme <THEME> Theme selection (light, dark, auto) [default: auto]
--qr [<BASE_URL>] Generate QR code for server address. Optionally specify a base URL (e.g., http://192.168.1.100:6419) to override the default local address
-b, --open-browser [<BASE_URL>] Automatically open browser after starting the server. Optionally specify a base URL (e.g., http://example.com:8080) to override the default local address
--shared-annotation Enable shared annotation mode. Annotations are stored in SQLite and synced across clients via WebSocket
-h, --help Print help
-V, --version Print version
Advanced Usage Examples
# Generate QR code for easy mobile access (uses local address)
# Generate QR code with a custom base URL (e.g., when using port forwarding or public IP)
# Auto-open browser after starting (opens local address)
# Auto-open with custom base URL (useful when behind reverse proxy)
# Server listens on localhost:6419, but accessible via proxy at example.com
# Combine options: QR code + auto-open + dark theme
# Complete example: Custom port, QR for public IP, auto-open local browser
# Enable shared annotation mode for real-time collaboration
Understanding URL Parameters:
Both --qr and -b options accept optional URL arguments:
QR Code (--qr option):
- Without argument (
--qr): Generates QR code forhttp://127.0.0.1:6419(local address) - With base URL (
--qr <BASE_URL>): Generates QR code for the specified URL - Use cases:
- Port forwarding:
--qr http://192.168.1.100:6419(LAN IP) - Public access:
--qr http://example.com/docs(public domain) - Mobile access:
--qr http://your-laptop-ip:6419(for phones on same network)
- Port forwarding:
Open Browser (-b option):
- Without argument (
-b): Openshttp://127.0.0.1:6419(local address) - With base URL (
-b <BASE_URL>): Opens the specified URL instead - Use cases:
- Reverse proxy: Server on
localhost:6419, proxy athttps://docs.example.com - SSH tunnel: Remote server tunneled to
http://localhost:8080 - Custom routing: Any URL that points to your running server instance
- Reverse proxy: Server on
Using Annotation Features
- Open a Markdown file in your browser
- Select any text to see the toolbar
- Choose highlight color (orange/green/yellow), strikethrough, or note
- Notes will appear on the right side of the page
- Click highlighted text to view associated notes
- Select highlighted text again to unhighlight
Two Annotation Modes
Local Mode (Default):
- Annotation data is stored in browser's LocalStorage
- Limited to a single browser, not shared across browsers or devices
- Suitable for personal reading and annotation
- No additional configuration needed
Shared Mode (--shared-annotation):
- Annotation data is stored in a SQLite database (default path:
~/.markon/annotation.sqlite) - Supports real-time synchronization across multiple clients via WebSocket
- Suitable for various collaboration scenarios:
- Single-user multi-device: Sync annotations across phone, tablet, desktop, etc.
- Team collaboration: Multiple users can simultaneously view and edit annotations on the same document
- Custom database path can be set via
MARKON_SQLITE_PATHenvironment variable
# Use shared annotation mode
# Customize database location
MARKON_SQLITE_PATH=/path/to/annotations.db
In both modes, you can use the "Clear Annotations" button at the bottom of the page to clear all annotations for the current page.
Important Notes
System Path Prefix
Markon uses /_/ as a reserved path prefix for all system resources (CSS, JavaScript, WebSocket, favicon). This ensures complete separation between system files and your content:
- Reserved path:
/_/(only this specific prefix) - What this means: Do NOT create a directory named
_(single underscore) in your working directory root - What you CAN do:
- ✅ Create directories like
_build/,__pycache__/,_test/,_cache/(different from_) - ✅ Create directories like
ws/,static/,css/,js/(no conflict!) - ✅ Use any file or directory names that don't start with exactly
_/
- ✅ Create directories like
Examples:
# ❌ This will conflict with system paths
# ✅ All of these are perfectly fine
When using reverse proxy: Make sure to configure your proxy to forward the /_/ path. See REVERSE_PROXY.md (中文版) for detailed configuration examples for Nginx, Caddy, Apache, and Traefik.
Supported Markdown Features
- Headings (H1-H6)
- Bold/Italic/Strikethrough
- Lists (ordered/unordered)
- Task Lists (- [ ] / - [x])
- Tables
- Code Blocks (with syntax highlighting)
- Block Quotes
- Links and Images
- Horizontal Rules
- Footnotes
- Emoji (:emoji_name:)
- Mermaid Diagrams
- GitHub Alerts ([!NOTE], [!TIP], etc.)
Mermaid Diagram Example
Markon supports Mermaid diagram rendering using ```mermaid code blocks:
```markdown ```mermaid graph TD A[Start] --> B{Decision} B -->|Yes| C[Action 1] B -->|No| D[Action 2] ``` ```
Supported diagram types:
- Flowcharts (graph/flowchart)
- Sequence Diagrams (sequenceDiagram)
- Pie Charts (pie)
- Gantt Charts (gantt)
- Class Diagrams (classDiagram)
- State Diagrams (stateDiagram)
- And more...
Emoji Support
Use standard emoji shortcodes:
:smile: :heart: :rocket: :tada: :sparkles:
Result: 😄 ❤️ 🚀 🎉 ✨
GitHub Alerts Example
Create alert boxes using special blockquote syntax:
Supported types:
- NOTE (blue) - General information
- TIP (green) - Helpful tips or suggestions
- IMPORTANT (purple) - Key information
- WARNING (yellow) - Important warnings
- CAUTION (red) - Dangerous or critical warnings
Project Origin
This project is a Rust port of go-grip with added Medium-style annotation features.
Key Differences from go-grip
| Feature | go-grip | markon |
|---|---|---|
| Language | Go | Rust |
| GitHub Alerts | ✅ | ✅ |
| Emoji | Custom mapping | Unicode (emojis crate) |
| Medium Annotations | ❌ | ✅ |
| Hot Reload | ✅ | ❌ |
| Auto Browser Open | ✅ | ✅ |
| QR Code Generation | ❌ | ✅ |
| Print Optimization | ✅ | ✅ |
Tech Stack
Backend
- Markdown Parsing: pulldown-cmark
- Syntax Highlighting: syntect
- HTTP Server: axum + tokio
- Template Engine: tera
- Static Asset Embedding: rust-embed
- Emoji: emojis
Frontend
- Diagram Rendering: Mermaid.js
- Styling: GitHub Markdown CSS
- Annotations: Vanilla JavaScript + LocalStorage
Development
Project Structure
markon/
├── src/
│ ├── main.rs # Entry point
│ ├── server.rs # HTTP server
│ ├── markdown.rs # Markdown renderer
│ └── assets.rs # Static asset management
├── assets/
│ ├── css/ # Stylesheets
│ │ ├── github-markdown-dark.css
│ │ ├── github-markdown-light.css
│ │ ├── github-print.css
│ │ └── editor.css # Annotation styles
│ ├── js/ # JavaScript
│ │ ├── mermaid.min.js
│ │ └── editor.js # Annotation logic
│ └── templates/ # HTML templates
│ ├── layout.html
│ └── directory.html
├── Cargo.toml
├── README.md
└── README.zh.md
Build
# Debug mode
# Release mode
# Run tests
# Lint
# JavaScript lint
Contributing
We welcome all forms of contributions! Whether it's reporting bugs, suggesting new features, or submitting code improvements.
How to Contribute
- Report Issues: Submit bug reports or feature requests in GitHub Issues
- Submit PRs:
- Fork the project
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code Standards
Before submitting a PR, please ensure:
- ✅ Run
cargo testto ensure all tests pass - ✅ Run
cargo clippyto ensure code follows Rust best practices - ✅ Run
cargo fmtto format the code - ✅ Run
npx eslint assets/js/editor.jsfor JavaScript code
License
Apache License 2.0
Acknowledgments
- go-grip - Original project
- GitHub Markdown CSS - Styling source
- Medium - Annotation feature inspiration
- All open-source contributors
Links
- Original project: https://github.com/kookyleo/go-grip
- GitHub Markdown CSS: https://github.com/sindresorhus/github-markdown-css
- Mermaid documentation: https://mermaid.js.org/