A fast, native macOS app for reading Markdown files.
Drop a
.mdon the icon (or set Markdown Preview as your default handler) and get a clean, scrollable preview with a real document outline — no Electron, no browser tab.
Markdown Preview is available in the official Homebrew cask repository:
brew install --cask markdown-previewOr grab the latest signed and notarized DMG from the 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…
Single source newlines remain visible by default. Enable Settings → General → Reading → Strict line breaks to let ordinary source lines flow into paragraphs in reading view and Quick Look. Two trailing spaces or a backslash still create an explicit line break; blank lines still separate paragraphs. Reopen an existing Quick Look preview after changing this setting.
- 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. - Read Mode — select and copy text, follow links, and browse tables without changing the document. Switch to Edit Mode to edit tables or toggle task checkboxes.
- Edit Mode — edit Markdown in place with a formatting toolbar for headings, emphasis, lists, quotes, code, and links. Table cells show inline formatting until focused, then reveal their Markdown syntax for editing. Task markers become checkboxes once you finish typing the closing bracket; Enter continues a task list, and Enter on an empty task exits it. Toggle it from the toolbar or with ⌘E, then save with ⌘S.
- 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 (via the officialcopy-texextension). - Document outline — sidebar TOC that mirrors your headings; click to jump.
- File navigator — browse Markdown files in the sidebar. Click a folder's name, icon, or empty row space to expand or collapse it, or use its disclosure triangle. Click a file to open it in the current reading or editing mode.
- Inspector panel — toggleable side panel with file metadata.
- In-document search — toolbar search field plus standard ⌘F / ⌘G / ⌘⇧G for next/previous match.
- Search for Document — find a file by name, as against searching inside one. ⇧⌘O, or a toolbar button you can drag in via View → Customize Toolbar…, opens a draggable floating palette over the current document, with native Liquid Glass on macOS 26 and later (Escape or clicking outside dismisses it); the palette remembers where you drag it; the list stays hidden until you type a nonblank query, then updates in place when each search finishes, with the matched letters picked out in bold and a breadcrumb path beneath each filename. ↑ and ↓ move through the results (Home, End, Page Up and Page Down work too). ↩ opens the highlighted file in the current tab, ⌘↩ in a new tab, ⌥↩ in a new window. It searches the folder the sidebar has mounted and recognizes the same Markdown extensions as the navigator, but leaves out dependency and build folders (
node_modules,vendor,build,DerivedData,Pods,target, and similar), the contents of packages such as.appor.rtfdbundles, and folders more than 12 levels deep. In very large projects it indexes the first 20,000 files and says so. - 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 text up or down in Read or Edit mode with the toolbar's A A control or ⌘+ / ⌘− / ⌘0, or pinch the trackpad in Read mode. Discrete Safari-style stops from 50% to 300%.
- Customizable toolbar — drag in the items you actually use (Print, Copy, Zoom, Sidebar, Open With, Inspector, Share, Search, Search for Document) 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 (great for pasting into ChatGPT / Claude), 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. - Command line tools — install
mdp,md-preview, andmarkdown-previewfrom the app menu, then open files or folders from any shell with commands likemdp README.mdormdp .. - 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), the same shape ascursor://file/…. Percent-encode special characters in the path (a space becomes%20). - Default handler — offers to register itself as the default
.mdopener on first launch. - Fast opening — a document you open again shows its first screen at once from a saved image while the page loads (documents that look final on first paint, so not ones with images, math, Mermaid diagrams, or code highlighted after load); the app keeps the images for the 40 most recent documents in its own cache, and they never leave your Mac. While a document window is open, the next document reuses a web view prepared in the background; closing the last window frees it.
.md, .markdown, .mdown, .mdx, .txt
UTI: net.daringfireball.markdown
- macOS 15 or later
- Apple Silicon or Intel
git clone git@github.com:pluk-inc/markdown-preview.git
cd markdown-preview
open markdown-preview.xcodeprojBuild and run the markdown-preview scheme. Swift Package Manager will resolve Sparkle, Sentry, and swift-markdown on first build.
Release builds submit native crash reports to the pluk-inc/markdown-preview Sentry project. The integration does not collect performance traces, session data, breadcrumbs, network requests, user information, document contents, or file paths. Users can turn reporting off in Markdown Preview > Settings > Privacy; on later launches, the Sentry SDK will not initialize at all.
The committed DSN is a public client key. Release archives upload the app dSYM with sentry-cli; authenticate locally with sentry-cli login and keep that authentication token outside the repository.
Release builds can submit at most one anonymous app became active event per installation per UTC day when Markdown Preview becomes active. The event contains a random installation identifier, app version, macOS major version, processor architecture, locale country or region, and the flag that prevents PostHog from creating a person profile. It is used to count daily and monthly active installations and understand basic platform compatibility. It does not contain document contents, file names or paths, actions, screens, precise location, personal information, or advertising identifiers. Users can disable it from Settings > Privacy.
The PostHog project token is injected from the gitignored Secrets.xcconfig. Copy Secrets.xcconfig.example to Secrets.xcconfig and set POSTHOG_PROJECT_TOKEN before making a release build. If the token is absent, or for a Debug build, analytics remains disabled. Every event disables GeoIP enrichment, and the PostHog project must also be configured to discard IP data in Project Settings > General.
md-preview/ Main app target (AppKit, WKWebView)
quick-look/ Quick Look extension (.appex)
scripts/ Release & rollback automation
Version.xcconfig Marketing & build version (single source of truth)
appcast.xml Sparkle update feed
Releases are driven by Amore — it handles building, code signing, notarization, DMG creation, S3 upload, and Sparkle appcast publishing in one shot.
To prepare a release PR, start from latest main, update both MARKETING_VERSION and CURRENT_PROJECT_VERSION in Version.xcconfig, and add the matching CHANGELOG.md entry with contributor credits. Submit these together in a ready PR; see the release-process skill for naming and validation.
When ready to publish the prepared release, run the following from a clean working tree. This builds, notarizes, uploads, tags, and publishes the release:
./scripts/release.shUse ./scripts/rollback-release.sh to revert the appcast pointer if a release misbehaves.
Pull 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).
Markdown Preview is free and MIT-licensed. If it saved you a browser tab, you can buy us a coffee.
- Amore — MacOS release automation (signing, notarization, DMG, hosting, appcast)
- 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 - Sparkle — Auto-update framework
- Sentry — Privacy-filtered native crash reporting
- LottieFiles — Animated README logo



