Belvedere is a native macOS app for reading Markdown files — fast, no Electron, no browser tab — hardened so that opening a file someone else sent you is safe by default: nothing in a document can reach the network, run something, or fake a sign-in prompt.
Drop a
.mdon the icon (or set Belvedere as your default handler) and get a clean, scrollable preview with a real document outline — and nothing the document does reaches the network.
brew tap inquinity/tap
brew trust inquinity/tap # or: brew trust --cask inquinity/tap/belvedere, to trust only this cask
brew install --cask belvederebrew tap adds inquinity/homebrew-tap as a
software source — it's a public repository you can read before trusting it. brew trust
records that review: without it, brew install refuses to load a cask from a non-official
tap at all (Error: Refusing to load cask … from untrusted tap …). Homebrew records where
the app came from either way, and brew upgrade --cask belvedere is how updates arrive
(there is no auto-updater — see below). Each release is signed with a Developer ID and
notarized by Apple, so Gatekeeper verifies it before install without a manual override.
You can also download the latest release directly, as a DMG, from the tap's Releases page.
Edit Markdown directly with a native formatting toolbar:
Quick Look preview — spacebar a .md in Finder:
Customize the toolbar — drag in Print, Copy, Zoom and the rest from View → Customize Toolbar…
Reading, editing, printing, PDF export and Quick Look are the core experience, and work the way you'd expect from a native Mac app. Everything below is what's added on top:
It never connects on its own — no crash reporting, no usage analytics, no auto-updater.
The code that would have sent any of that is gone, not just disabled; new versions arrive
only through brew upgrade.
A document can't reach the network, or read files outside its folder, just by being opened. Remote images, stylesheets, fonts and scripts are blocked in the app, the editor, and Quick Look — a remote image shows as a placeholder naming its host instead of loading, so opening a document never tells its author that you read it. Local images load from the document's own folder, or from a wider folder you explicitly opened; anything outside that boundary shows a placeholder with a one-click, not-remembered Load button.
A document can't draw a fake sign-in prompt. Text fields, dropdowns, and other form
controls are stripped from rendered content — a <form> that survives sanitization
elsewhere as inert markup renders as nothing here. Task-list checkboxes still work.
A link never runs or installs something on a click. A link to an app, script, installer, or disk image is shown in Finder instead of started, wherever it points. Links to ordinary documents open as usual.
A Save button — in the toolbar, lit whenever the document has unsaved changes. Leaving edit mode asks Save / Revert… / Continue instead of discarding silently; ⌘S and Save As… work after leaving edit mode too.
- Native rendering —
WKWebViewpipeline backed by swift-markdown, with heading anchors and link handling. Barehttp://andhttps://URLs are clickable in the app and Quick Look previews. - Edit Mode — edit Markdown in place with a formatting toolbar for headings, emphasis, lists, quotes, code, and links. Toggle it from the toolbar or with ⌘E.
- Mermaid diagrams — fenced
mermaidcode blocks render as diagrams in both the app and Quick Look previews, using a bundled renderer so previews work offline without a CDN request. - Math equations — LaTeX inline (
$x_1 + x_2$), display ($$\int_0^1 x^2\,dx$$), and fencedmathblocks render with a bundled KaTeX. Selecting a rendered formula and copying yields the original LaTeX source. - Document outline — sidebar TOC that mirrors your headings; click to jump.
- File navigator — browse Markdown files in the sidebar. Opening a folder (rather than a single file) also sets the containment boundary described above.
- Inspector panel — toggleable side panel with file metadata.
- In-document search — toolbar search field plus standard ⌘F / ⌘G / ⌘⇧G for next/previous match.
- Open With — switch to your real editor (VS Code, Cursor, Zed, Sublime, BBEdit, Nova, CotEditor, TextMate, MacVim, Xcode, TextEdit) without leaving the preview. The list filters to apps that actually declare an editor role for Markdown, and remembers your pick.
- Open in LLM — send the current Markdown file to Codex, Claude, or ChatGPT from the toolbar. Supported apps open with file or folder context where possible, with a copy-and-open fallback for longer prompts.
- Text zoom — bump preview text up or down with trackpad pinch, the toolbar's A A control, or ⌘+ / ⌘− / ⌘0. Discrete Safari-style stops from 50% to 300%.
- Customizable toolbar — drag in the items you actually use via View → Customize Toolbar… Standard AppKit affordance, your layout sticks across launches.
- Share = copy the source — the share toolbar feeds the picker the Markdown text itself, so Copy writes the raw source to the clipboard, and Mail, Messages, and Notes get the content in the body instead of a file URL.
- Quick Look extension — system-wide
.mdpreviews from Finder spacebar, Spotlight, and Mail attachments without launching the app. Subject to the same network and containment restrictions above. - URL scheme — open a file or folder from a browser link or another app with
md-preview://file/<absolute path>(e.g.md-preview://file/Users/me/project/README.md). Percent-encode special characters in the path. - Default handler — offers to register itself as the default
.mdopener on first launch.
Not in Belvedere: the command-line tools installer (mdp, md-preview) is removed, along
with the permission to control Terminal it needed.
.md, .markdown, .mdown, .mdx, .txt
UTI: net.daringfireball.markdown
- macOS 15 or later
- Apple Silicon or Intel
git clone git@github.com:inquinity/belvedere.git
cd belvedere
just buildRequires just (brew install just). just --list shows
the rest of the fork's build/release tasks, which wrap the scripts in bin/. Swift Package
Manager resolves swift-markdown on first
build — Sparkle and Sentry are not dependencies here; both were removed entirely.
md-preview/ Main app target (AppKit, WKWebView)
quick-look/ Quick Look extension (.appex)
bin/ This fork's build & release scripts (build.sh, publish-release.sh, …)
scripts/ Upstream's own tooling, untouched so syncs apply cleanly
Version.xcconfig Marketing & build version (single source of truth)
Releases are cut locally and published to the Homebrew tap — see docs/RELEASE-AUTOMATION.md for the full flow. In short:
just release revision # or minor / major — builds, signs, notarizes, commits, tags
just publish --go # pushes the release and bumps the tap's caskPull requests are welcome. For larger changes, please open an issue first to discuss what you'd like to change.
- Fork the repo and create your branch from
main. - Run the app and verify the change end-to-end (UI changes need a manual smoke test — there's no UI test suite yet).
- Keep PRs focused; one logical change per PR.
- Match the existing Swift style (no formatter is enforced; mirror nearby code).
A fix that belongs in Markdown Preview itself — rather than being specific to this fork's hardening — is usually better sent there directly; see the upstream contribution track in docs/FORK-NOTES.md for how this fork handles that split.
- swift-markdown — Markdown parser (Apple, cmark-gfm-backed)
- Mermaid — Bundled diagram renderer for
mermaidfenced code blocks - KaTeX — Bundled math typesetter for inline
$…$, display$$…$$, and```mathblocks
Belvedere is a fork of Markdown Preview by pluk-inc, hardened to remove its outbound network connections and tighten how it handles untrusted documents. See docs/FORK-NOTES.md for exactly what differs and why. For upstream's own branding, screenshots, and ways to support that project, see its repository directly.
Belvedere and upstream Markdown Preview install side by side — different bundle ID, different
icon — so having one doesn't remove or conflict with the other. Markdown Preview itself is
brew install --cask markdown-preview from the
official cask repository.