allenguarnes.com

posts/2026-10-20 — less +F

VOMD: A Tiny, Fast View-Only Markdown Viewer for the Linux Desktop

October 20th, 2026 #opensource#linux#rust

I read a lot of Markdown.

READMEs, changelogs, notes, docs that ship inside a tarball. Most of the time I don't want to edit any of it. I just want to look at it, the way it would look on GitHub, and then close the window.

On my desktop that turned out to be weirdly awkward. Double-clicking a .md file either opened it as plain text, or launched something much bigger than the job: an editor with a preview pane, or a browser and an extension. Both work. Neither feels like "open this file and show it to me."

So I wrote VOMD, short for View-Only Markdown: a tiny, fast Markdown viewer for the Linux desktop.

Project Links

The problem: reading should be cheaper than editing

What I wanted was simple to describe:

  • Double-click a .md file
  • It appears, rendered the way GitHub shows it
  • It appears now, not after a splash screen

That last part was the real requirement. If a viewer takes longer to open than it takes me to read the first paragraph, I'll go back to cat.

The approach: no web engine, no toolkit

The usual way to render Markdown is to turn it into HTML and hand it to a browser engine. That gets you a lot for free, and it also gets you a browser engine.

I went the other way and set myself a few hard constraints:

  • One binary. The release build is a single 3.9 MB file.
  • Fonts built in. Inter for text, JetBrains Mono for code, and Lucide for the icons are embedded, so it looks the same everywhere.
  • No web engine and no GUI toolkit. VOMD parses with pulldown-cmark, opens its window with winit, shapes text with swash, and draws into a plain software buffer with softbuffer. Everything you see, it lays out and paints itself.
  • No network unless you ask. More on that below.

It's written in Rust, and the release profile is tuned for size (opt-level = "z", fat LTO, stripped). The result is that a document opens in well under a tenth of a second.

What it does

VOMD is view-only on purpose, but "view" covers more ground than I expected once I started using it daily.

Markdown coverage

It handles CommonMark and GitHub Flavored Markdown: tables, task lists, strikethrough, footnotes, alerts (> [!NOTE] and friends), and autolinks. YAML front matter is hidden, which matters for me because half my notes have it. Math and Mermaid show as text and code.

Raw HTML is never run. Tags are stripped and their text is kept, and a few tags (<b>, <img>, <a>, <br>, and similar) are rendered the way GitHub renders them.

Looks

Light and dark themes follow the system, and T cycles system, light, and dark. Zoom runs from 50% to 300% (Ctrl + = / - / 0, or Ctrl + wheel). HiDPI scaling follows the system scale factor.

Links and navigation

#anchors scroll within the document. Relative .md links open in the same window, and Back (Backspace, Alt+←) returns. Web links open in your browser. [ and ] jump between headings, and j/k, g/G work if your fingers expect them to.

Images

Local PNG and JPEG images are decoded lazily, so a long document full of screenshots doesn't pay for images you haven't scrolled to. Remote images stay as placeholders until you press I for that document.

Selecting and copying

You can drag to select, double-click a word, triple-click a paragraph, or Ctrl+A for everything. Ctrl+C copies it as plain text: list items keep their - , quoted lines keep their > , and table cells are tab-separated. On X11 and Wayland, a mouse selection is also the primary selection, so middle-click paste works.

Code blocks get a copy button in the upper right corner when the pointer is over them, like on GitHub. It copies the code as written, without the language tag and without a trailing line break, and shows a check mark for two seconds.

Live reload and large files

When the window gets focus, a document that changed on disk is shown again at the same place. So I keep VOMD open next to my editor, save, click over, and I'm looking at the new version without losing my scroll position.

A 5 MB document opens in under 100 ms. Files over 10 MB still render, with a notice.

Install

The current release is 1.2.0, and every release is x86-64 Linux.

Arch Linux

The packages aren't on the AUR yet, so for now you build one from a clone with makepkg:

sh
git clone https://github.com/allenguarnes/vomd
cd vomd/packaging/aur/vomd-bin
makepkg -si

vomd-bin installs the release binary, which is the small one and runs on any x86-64 CPU. If you'd rather build from source, use packaging/aur/vomd instead. It follows your makepkg.conf, so on CachyOS (with its -C opt-level=3 -C target-cpu=native flags) you get a larger, faster binary that only runs on the CPU it was built on.

Debian and Ubuntu

Each release has a .deb for Debian 12 or newer and Ubuntu 24.04 or newer:

sh
sudo apt install ./vomd_*_amd64.deb

AppImage

There's also an AppImage for any x86-64 distribution with glibc 2.36 or newer. It doesn't bundle libraries; it loads the system's Wayland or X11 ones at startup:

sh
chmod +x vomd-*-x86_64.AppImage
./vomd-*-x86_64.AppImage README.md

It needs FUSE to mount itself. Without it, run it with --appimage-extract-and-run.

Release tarball

The tarball has the binary, the desktop file, and the icon:

sh
tar xf vomd-*-x86_64-linux.tar.gz
cd vomd-*-x86_64-linux
install -Dm755 vomd ~/.local/bin/vomd
install -Dm644 vomd.desktop ~/.local/share/applications/vomd.desktop
install -Dm644 vomd.svg ~/.local/share/icons/hicolor/scalable/apps/vomd.svg
xdg-mime default vomd.desktop text/markdown

That last line is the one that makes double-clicking a .md file open VOMD.

From source

You need a stable Rust toolchain:

sh
cargo build --release
# The smallest build: no images, no clipboard, system fonts only
cargo build --release --no-default-features

The Cargo features are images, remote-images, embed-fonts, and clipboard, all on by default.

Settings

Settings live in ~/.config/vomd/settings.ini (strictly, $XDG_CONFIG_HOME/vomd/settings.ini). The file is optional, it's plain key = value lines, and it's applied as soon as the window gets focus. The toolbar's gear button creates it with every key listed and commented out.

A few keys I actually touch:

ini
# system, light, dark
theme = system
# 50 to 300
zoom = 100
# 10 to 32
font_size = 16
# 40 to 200 characters
line_width = 80
# true lets the text span the window (line_width is ignored)
wide = false
# ask, never, always
remote_images = ask
# default (built in), or an installed family such as Noto Sans
font_sans = default

Theme, zoom, toolbar, wide layout, and window size are saved automatically when you change them, so most people will never open the file.

Privacy

This was a constraint I cared about from the start: a viewer should not phone anywhere just because you opened a file.

VOMD makes no network requests of its own. Remote (http/https) images show as placeholders until you press I (or click the toolbar's image button) for that document. Only then are they fetched, using the system curl, at most 4 at a time, each limited to 12 MiB and 15 seconds, and kept in memory only.

The default is remote_images = ask. You can set it to never to remove the option entirely, or always to load them for every document, but be aware that always lets any document you open contact the servers its images live on.

Limitations

Being honest about what it doesn't do yet:

  • Linux only for now. The code compiles for Windows and macOS, but those are untested and unsupported.
  • No table of contents panel yet. It's planned.
  • No screen-reader support. AccessKit would add too much to the binary for now.
  • SVG, GIF, and WebP images show as placeholders. EXIF orientation isn't applied either.
  • No keyboard selection. Selecting is mouse-driven; Ctrl+A and Ctrl+C are the keyboard's way to copy, and the code-block copy button can't be reached from the keyboard.
  • Drag-and-drop works on X11 only, because winit doesn't support it on Wayland. On Wayland, open files with Ctrl+O or the toolbar's folder button.

Closing thoughts

VOMD is a small tool with a narrow job. It doesn't edit, it doesn't sync, and it doesn't try to be a notes app. It opens Markdown fast and gets out of the way.

It's MIT licensed, and the embedded fonts and icons keep their own licenses (Inter and JetBrains Mono under the SIL OFL 1.1, Lucide under ISC).

If you try it and something renders wrong, open an issue on GitHub with the Markdown that broke it. That's the most useful bug report a viewer can get.