MD Preview / Engineering note
Building a Native Markdown Previewer for AI-Generated Docs with Rust and WebView
AI coding tools now produce a steady stream of Markdown: README drafts, plans, task specs, architecture notes, Mermaid diagrams, and KaTeX-heavy technical docs. I wanted a small local window to read those files beside my editor, without launching a full IDE or shipping an Electron app.
The shape of the tool
MD Preview is intentionally narrow. It opens a local Markdown file, renders it, watches it, and refreshes when the file changes. It is not trying to become a note system, plugin host, or full writing studio.
That scope made Rust and the system WebView a good fit. Rust owns the file IO, Markdown pipeline, window lifecycle, and packaging. The operating system already ships a capable web renderer, so the app uses wry to talk to WebKit on macOS, WebView2 on Windows, and WebKitGTK on Linux instead of bundling Chromium.
Markdown first, enhancements only when needed
The base Markdown pass uses pulldown-cmark. A regular document should become visible quickly, even if it does not need math, diagrams, or syntax highlighting. Heavier rendering assets are embedded offline and loaded after first paint or only when the document actually uses them.
let opts = Options::ENABLE_TABLES
| Options::ENABLE_STRIKETHROUGH
| Options::ENABLE_TASKLISTS
| Options::ENABLE_HEADING_ATTRIBUTES;
let parser = Parser::new_ext(markdown, opts);
let mut html_out = String::new();
html::push_html(&mut html_out, parser);
That keeps the simple path simple while still covering the documents people really have: code blocks, GitHub-flavored tables, task lists, local images, KaTeX formulas, and Mermaid diagrams.
Why not Electron?
Electron is powerful, but Markdown preview is a small job. For this specific use case, bundling a whole Chromium runtime felt out of proportion. A system WebView keeps the app small, uses the platform renderer, and still gives enough HTML/CSS/JavaScript surface for Markdown rendering.
The tradeoff is that platform WebViews are not identical. The app has to respect macOS WebKit, Windows WebView2, and Linux WebKitGTK differences, especially around packaging, file URLs, printing, and GPU behavior. For a small previewer, that tradeoff is still worth it.
File watching is the feature
The most useful workflow is boring: keep your editor in source mode, save the file, and watch the preview update. MD Preview uses notify for file watching and guards reloads so rapid writes do not turn into unstable WebView refreshes.
That makes it useful beside Cursor, Claude Code, Codex, VS Code, Vim, Zed, or a script that writes Markdown reports. The preview window is just a small read-side companion.
Packaging lessons
The project ships macOS, Windows, and Linux release assets. macOS distribution requires the usual app bundle, signing, notarization, stapling, and a DMG that feels like a normal Mac app. Windows needs a GUI executable with the icon embedded. Linux remains the least uniform because the system WebKitGTK runtime is provided by the distribution.
The current release assets are roughly 4.5 MB for the macOS DMG, 1.8 MB for the Windows ZIP, and 2.4 MB for the Linux tarball.
Where it fits
If you want a Markdown editor, use a Markdown editor. If you want a knowledge base, use a knowledge base. MD Preview is for the smaller but frequent moment when a local .md file needs to be readable now.
Repo: github.com/vorojar/md-preview
Disclosure: this engineering note was drafted with assistance from Codex and reviewed in the project context before publication.