A Markdown Editor That Lives in Your Browser, Desktop, and a Single URL.
Fast GitHub-style Markdown editing with live preview, diagrams, LaTeX, syntax highlighting, PDF export, and multi-tab support across web, desktop, and Docker.
🌐 English • 简体中文 • 日本語 • 한국어 • Português (Brasil)
Live Production Demo • Documentation Wiki • Issue Tracker • Releases
📂 Table of Contents (Click to expand)
Markdown Viewer is an advanced, fully client-side editing suite and previewer optimized for a professional documentation workflow. Running completely inside the browser, it renders GitHub-Flavored Markdown (GFM), math formulas, and architectural diagrams in real time.
Designed with privacy and performance at its core, the application performs all parsing in a background worker thread, employs incremental DOM patching to minimize browser repaints, and supports native offline capabilities via a Service Worker proxy. It is also packaged as a lightweight native desktop shell using the Neutralinojs framework.
Type Markdown in the custom editor and watch it render in real-time in the live preview pane.
Render inline and display mathematical formulas natively using the MathJax typesetting engine.
Generate flowcharts, Gantt charts, and sequence diagrams with zoom, pan, and SVG export controls.
Parse and visualize GeoJSON and TopoJSON map files directly inside your preview area.
📦 STL 3D Model Renderer (View Release Demo v3.7.5)
Render and interact with STL (ASCII/Binary) files featuring perspective controls, flat shading, and reset controls.
Render client-side ABC music notation directly to beautifully styled SVG sheet music with full offline rendering support.
Organize multiple open files inside drag-and-drop tabs with local session persistence and tab context menus.
Perform scoped searches using regular expressions, syntax scopes, and side-by-side visual diff replacements.
Quickly insert markdown elements, tables, emojis, and symbols using dedicated formatting toolbar modals.
Access a fully localized user interface with support for English, Simplified Chinese, Japanese, Korean, Portuguese, and more.
Export your documents to raw Markdown, centered inline HTML, high-quality PNG images, or paginated PDF with re-engineered page breaks.
🔗 Serverless Compressed URL Sharing (Click to Try)
Share view or edit mode documents database-free via zlib DEFLATE compressed URL hashes.
Drag and drop local files, or import directories recursively directly from public GitHub repositories.
Compile Markdown off-thread using a background Web Worker and cache gutter wrapping coordinates to avoid layout thrashing.
Work offline via local Service Worker caching, protected by SHA-384 subresource integrity check policies.
Format and render official GitHub-style admonitions (> [!NOTE], etc.) with correct color schemes and icons.
Track word count, character count, and estimated reading time dynamically via a live status counter.
Switch instantly between light and dark themes with CSS-variable based syntax highlighting.
Restore and redo editor history individually per document tab using custom-built in-memory history state stacks.
Increase typing efficiency with native keybinds for file saving, sync scrolling, tab management, and text editing.
Drag markdown files anywhere onto the browser window to instantly import and open them in the workspace.
Keep the editor and preview pane aligned using scroll lock mechanisms and requestAnimationFrame coordinates mapping.
Markdown Viewer is structured as a client-side single-page application (SPA). The diagram below outlines how the UI thread, background worker, service worker, browser cache, native desktop bridges, and third-party libraries interact.
graph TD
%% Client Interface Group
subgraph UI ["Client Interface (Main Thread)"]
HTML["index.html<br>(DOM Tree)"]
CSS["styles.css<br>(Custom Themes & Reset)"]
Script["script.js<br>(UI Orchestration)"]
Editor["Markdown Editor<br>(Textarea + Gutter)"]
Preview["Preview Pane<br>(Direct DOM Render Area)"]
Modal["Mermaid Modal<br>(Zoom & Drag-to-Pan)"]
i18n["i18n Localization Engine<br>(Dictionary translation)"]
DOMPurify["DOMPurify.js<br>(Strict XSS Sanitizer)"]
end
%% Background Web Worker Group
subgraph Worker ["Web Worker (Background Thread)"]
PWorker["preview-worker.js<br>(Off-Thread Compiler)"]
MarkedLib["Marked.js<br>(GFM Parser)"]
HljsLib["Highlight.js<br>(Syntax Color)"]
end
%% Storage Group
subgraph Storage ["Local Storage & Network Proxy"]
LS["localStorage<br>(Tabs, Settings, Shadow Cache)"]
Cache["Browser Cache<br>(Service Worker sw.js)"]
LocalAssets["Local Static Assets<br>(Icons, sample.md, manifest)"]
end
%% Third-Party Utilities
subgraph CDNs ["Third-Party CDN Libraries (Lazy Loaded / Local Offline Mapped)"]
MathJax["MathJax.js<br>(LaTeX Math)"]
Mermaid["Mermaid.js<br>(Diagrams)"]
PDF["jsPDF & html2canvas<br>(PDF/PNG Export)"]
Pako["Pako.js<br>(DEFLATE share encoder)"]
JoyPixels["JoyPixels.js/css<br>(Emoji Tool)"]
Leaflet["Leaflet.js/css & TopoJSON<br>(Interactive Maps)"]
ThreeJS["Three.js, loaders & controls<br>(3D STL Viewer)"]
Abcjs["abcjs-basic.js<br>(Sheet Music)"]
end
%% Native Desktop Layer
subgraph Desktop ["NeutralinoJS Desktop Shell"]
Neu["Neutralino.js Bridge<br>(Native File System APIs)"]
end
%% Interactions
Editor -- "1. Input Keystrokes" --> Script
Script -- "2. Size-Aware Debounced Text" --> PWorker
PWorker -- "3. Load Scripts" --> MarkedLib
PWorker -- "3. Load Scripts" --> HljsLib
PWorker -- "4. Returns Compiled HTML Blocks & Hashes" --> Script
Script -- "5. Sanitize HTML segments" --> DOMPurify
DOMPurify -- "6. Incremental Patching / Full Fallback" --> Preview
Script -- "7. Debounced State Auto-Save" --> LS
LS -. "Shadow Cache Sync" .-> Script
%% Scroll sync loop
Editor -- "Proportional Scroll Sync (RAF)" --> Preview
Preview -- "Proportional Scroll Sync (RAF)" --> Editor
%% Dynamic Loading triggers
Script -- "Lazy Load (Math string detected)" --> MathJax
Script -- "Lazy Load (Mermaid class detected)" --> Mermaid
Script -- "Lazy Load (On Export click)" --> PDF
Script -- "Lazy Load (On Share click/hash load)" --> Pako
Script -- "Lazy Load (Colons detected)" --> JoyPixels
Script -- "Lazy Load (geo/topojson map class)" --> Leaflet
Script -- "Lazy Load (stl-viewer class)" --> ThreeJS
Script -- "Lazy Load (abc music class)" --> Abcjs
%% Downstream Rendering outputs
MathJax -- "Inject Math formulas" --> Preview
Mermaid -- "Draw SVGs + Toolbars" --> Preview
Preview -- "Click toolbar Zoom button" --> Modal
PDF -- "Capture sandboxed canvas (useCORS)" --> Script
JoyPixels -- "Render emojis" --> Preview
Leaflet -- "Render interactive maps" --> Preview
ThreeJS -- "Render 3D STL model" --> Preview
Abcjs -- "Render sheet music" --> Preview
%% Network Proxy Caching
Cache -. "Network-First (App Assets)" .-> HTML
Cache -. "Network-First (App Assets)" .-> Script
Cache -. "Network-First (App Assets)" .-> CSS
Cache -. "Network-First (App Assets)" .-> PWorker
Cache -. "Network-First (App Assets)" .-> sw.js
Cache -. "Stale-While-Revalidate" .-> LocalAssets
Cache -. "Cache-First (Lazy-loaded assets)" .-> CDNs
%% Desktop Logic
Script -- "Redirect CDNs to /libs/ offline copies" --> Script
Script -- "Access OS API if wrapped" --> Neu
index.html: Establishes layout structures, floating panel anchors, and imports CSS files alongside core scripts using defer hooks. It keeps the default fallback markdown inside a<script type="text/markdown" id="default-markdown">element.script.js: Operates as the central controller on the main UI thread. It tracks active tab states, drives the split resizing loops, handles drag-and-drop file imports, coordinates communication with the preview Web Worker, manages the multi-pass PDF layout engine, and applies language mappings.styles.css: Configures variables for Light/Dark themes, handles layout spacing, aligns the line number gutter visually with the text editor area, and provides theme stylings for code fences.preview-worker.js: Operates on a background thread. It parses large text structures, calculates hashes for each section, compiles Markdown to HTML usingmarked.js, applies syntax highlighting viahighlight.js, and posts parsed output back to the main UI thread.sw.js: A Service Worker serving as a local network proxy. It intercepts requests to cache static files on the client's device, enabling the application to run offline.
Because Markdown Viewer runs completely client-side utilizing standard HTML, CSS, and JavaScript, you can run it instantly directly from your filesystem:
- Clone or download the repository to your local machine.
- Open the repository folder in your system File Manager.
- Simply double-click
index.htmlto open the editor directly in your default web browser.
If you prefer running the application inside a containerized environment, choose one of the following methods:
Pre-built Docker Image (GHCR):
docker run -d \
--name markdown-viewer \
-p 8080:80 \
--restart unless-stopped \
ghcr.io/thisis-developer/markdown-viewer:latestOpen http://localhost:8080 in your browser.
Local Docker Compose Build:
git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git
cd Markdown-Viewer
docker compose up -dOpen http://localhost:8080 in your browser.
You can compile and run a native standalone desktop app (Windows, macOS, or Linux) locally from source:
- Clone the repository and navigate into the
desktop-app/directory:cd desktop-app - Open the
desktop-appdirectory in your system File Manager. - Open a command prompt/terminal inside this folder and run the installation and build commands:
# Install node dependencies and download Neutralino binaries npm install node setup-binaries.js # Synchronize resources with the main web app node prepare.js # Build/compile the application for Windows and other systems npm run build # Or build a standalone portable executable npm run build:portable
Note: You can also download prebuilt standalone binaries directly from the Releases page without compiling it yourself.
- Write Markdown in the left editor pane.
- Toggle Split/Editor/Preview modes using the view controls in the top toolbar.
- Insert elements (tables, images, checklists, alerts) using the Markdown formatting toolbar.
- Save or export your files using the Export dropdown.
| Action | Windows / Linux | macOS |
|---|---|---|
| Export raw Markdown | Ctrl + S |
⌘ + S |
| Copy plain text Markdown | Ctrl + C (with no text selected) |
⌘ + C (with no text selected) |
| Toggle Scroll Sync | Ctrl + Shift + S (in Split view) |
⌘ + Shift + S (in Split view) |
| Open a New Tab | Ctrl + T (desktop) / Alt + Shift + T (web) |
⌘ + T (desktop) / ⌥ + ⇧ + T (web) |
| Close the Active Tab | Ctrl + W (desktop) / Alt + Shift + W (web) |
⌘ + W (desktop) / ⌥ + ⇧ + W (web) |
| Open Find & Replace | Ctrl + F / Ctrl + H (replace) |
⌘ + F / ⌘ + H (replace) |
| Undo Last Edit | Ctrl + Z (when editor active) |
⌘ + Z (when editor active) |
| Redo Last Edit | Ctrl + Shift + Z / Ctrl + Y |
⌘ + Shift + Z / ⌘ + Y |
| Insert 2-space Indent | Tab (when editor active) |
Tab (when editor active) |
Markdown-Viewer/
├── index.html # Core application DOM structure & CDN scripts
├── script.js # Main thread controller, state orchestrator, scroll sync
├── preview-worker.js # Background web worker for Markdown compilation
├── styles.css # Theme stylesheets, layout grids, print layouts
├── sw.js # Progressive Web App (PWA) offline Service Worker
├── Dockerfile # Production Nginx Docker configuration
├── docker-compose.yml # Port mappings and local Compose orchestrator
├── README.md # Main repository readme
├── LICENSE # Apache 2.0 license file
├── assets/ # Image assets, gifs, and screenshots
├── wiki/ # Markdown documentation pages for GitHub Wiki
└── desktop-app/ # Native Neutralinojs desktop configuration & binaries
├── package.json # Node packaging and scripts
├── neutralino.config.json # Neutralino runtime configuration
├── prepare.js # Synchronizes root web files with desktop workspace
└── resources/ # Copied workspace assets compiled into desktop app
| Library Name | Version | Role in App | Loading Method |
|---|---|---|---|
| Marked.js | 9.1.6 | Parses markdown content to HTML elements. | Defer (Upfront) |
| Highlight.js | 11.9.0 | Adds syntax highlighting to code sections. | Defer (Upfront) |
| DOMPurify | 3.0.9 | Sanitizes HTML outputs against XSS. | Defer (Upfront) |
| FileSaver.js | 2.0.5 | Manages file saving on the client side. | Defer (Upfront) |
| js-yaml | 4.1.0 | Parses YAML frontmatter headers. | Defer (Upfront) |
| Bootstrap | 5.3.2 | Provides component structures and modal panels. | Upfront Script |
| Bootstrap Icons | 1.11.3 | Provides responsive vector symbols across formatting tools and headers. | Preloaded (Upfront) |
| GitHub Markdown CSS | 5.3.0 | Matches GitHub's exact light and dark typography rendering styles. | Upfront / Exports |
| Mermaid.js | 11.15.0 | Renders interactive flowcharts and diagrams. | Lazy-loaded on diagram find |
| MathJax | 3.2.2 | Renders mathematical LaTeX expressions. | Lazy-loaded on math find |
| jsPDF | 2.5.1 | Generates paginated PDF documents client-side. | Lazy-loaded on PDF request |
| html2canvas | 1.4.1 | Captures HTML layouts as canvas objects. | Lazy-loaded on PDF request |
| pako.js | 2.1.0 | Handles DEFLATE compression for share links. | Lazy-loaded on share request |
| JoyPixels | 9.0.1 | Renders standard emoji sets. | Lazy-loaded on emoji select |
| Leaflet | 1.9.4 | Powers interactive GeoJSON and TopoJSON map overlays. | Lazy-loaded on map detection |
| TopoJSON | 3.0.2 | Parses TopoJSON structures into standard GeoJSON coordinates. | Lazy-loaded on topojson detection |
| Three.js | r128 | Renders STL 3D models with canvas viewports. | Lazy-loaded on STL file detection |
| ABC Music Notation (abcjs) | 6.5.2 | Renders sheet music notation from raw text definitions. | Lazy-loaded on abc music detection |
We welcome community contributions! Please check our Contributing Guidelines Wiki before creating a pull request.
- Fork the repository and create a feature branch (
git checkout -b feature/your-feature). - Verify Code Style: Maintain a clean 2-space indentation style across HTML, CSS, and JS files. Ensure raw HTML structures are semantic. Avoid direct DOM queries inside processing workers.
- Conventional Commits: Write clear commit messages prefixed with
feat:,fix:,docs:,style:,refactor:,perf:, orchore:. - Testing: Test your revisions across Chrome, Firefox, Edge, and Safari viewports.
- Markdown Desk: A native macOS wrapper built using Tauri that adds native file-system handlers, menu bar integration, and auto-reload capabilities.
Thanks to everyone who has contributed to Markdown Viewer.
Markdown Viewer has grown from a lightweight Markdown parser into a full-featured, professional application with advanced rendering, workflow, and export capabilities. Compare the current version with the original version to see the progress in UI design, performance optimization, and feature depth.
This project is licensed under the Apache License 2.0. See the LICENSE file for the complete terms and conditions.
Developed and maintained by ThisIs-Developer.
- Bug Reports & Requests: Submit an Issue
- Documentation: Browse the Wiki


















