Reader.md
A native macOS rebuild of the markdown viewer, built in SwiftUI and AppKit. The whole shell — toolbar, sidebar, file search, outline, folder management, file watching, and SF Symbol icons — is native. The markdown content pane is a WKWebViewthat renders through bundled JS engines, because Mermaid diagrams and LaTeX math have no native equivalent.
Install
Direct download RECOMMENDED
Grab Reader.md.dmg from the latest release, open it, and drag Reader.md to Applications. The app is ad-hoc signed but not notarized, so the first launch needs one right-click → Open.
xattr -dr com.apple.quarantine "/path/to/Reader.md.app".Homebrew
Because the repo isn't named homebrew-*, tap it with its explicit URL once, trust the cask, then install:
# tap, trust, then install brew tap jnahian/reader.md https://github.com/jnahian/reader.md brew trust --cask jnahian/reader.md/reader.md brew install --cask reader-md
Already installed and Gatekeeper still complains? Clear the quarantine attribute:
xattr -dr com.apple.quarantine "/Applications/Reader.md.app"Upgrades come from the app's own Sparkle updater, so brew upgradeleaves the installed build alone. To uninstall, including preferences and caches:
brew uninstall --cask reader-md # remove the app brew uninstall --zap --cask reader-md # also wipe ~/Library data
Features
.md file (⌘O or double-click in Finder), whole folders, or a mix. Set Reader.md as your default markdown handler.rsyncs it read-only into a local cache. Auto-syncs on launch, manual re-sync, edit-in-place, and a cloud badge with sync/error state. Reuses your ~/.ssh config — no credentials stored.NSVisualEffectView material. Collapsible + resizable sidebar (⌘B, width persisted).Keyboard shortcuts
Command line
Homebrew puts reader on your PATH automatically. From the DMG, useFile → Install reader Command Line Tool….
readeropen a markdown file readeradd a folder to the sidebar reader . add the current directoryreader remote me@vps:/srv/docs add a remote (SSH) folderreader ls list configured foldersreader rmremove a folder git diff | reader - open piped markdown
reader drives the app rather than replacing it: each command hands a readermd:// URL to Reader.md. It behaves in scripts — a bad path or malformed command exits 1 with the reason on stderr; no arguments (or--help) prints usage and exits 0.
Architecture
The window's native toolbar over ContentView — a resizable/collapsible sidebar, the content pane, and a collapsible outline; overlays host the find bar and quick-open palette.
An ObservableObject (@MainActor) holding roots, selection, theme, search, outline, typography, layout, history, and find/export triggers; persists to UserDefaults.
A remote folder is rsync'd read-only into a stable local cache dir that registers as an ordinary root. Credentials come from your ~/.ssh config/keys — none are stored in-app.
An NSViewRepresentable around WKWebView. Swift pushes markdown / theme / font settings; JS posts the outline, active heading, word count, scroll progress, and link clicks back. Bundled marked, highlight.js, KaTeX, and Mermaid — no network.
Chrome surfaces use Apple's Liquid Glass on macOS 26, with an NSVisualEffectView fallback on 13–15. An FSEvents subtree watcher drives debounced live reload.
Build & run
Quick, for development
swift run ReaderMdDouble-clickable app
./make-app.sh
open "build/Reader.md.app"make-app.sh builds a release binary, assembles the bundle with resources, converts the icon to .icns, writesInfo.plist, ad-hoc code-signs, and producesbuild/Reader.md.zip for sharing. Or open the SwiftPM package in Xcode, select the ReaderMd scheme, and Run.
Requirements
macOS 13+. Liquid Glass appears on macOS 26 (Tahoe); earlier versions get theNSVisualEffectView fallback automatically.
Xcode 26 (or Swift 6.2+ with the macOS 26 SDK) to compile theglassEffect symbols. The deployment target stays at macOS 13.
rsync/ssh to hosts you add. Sync is read-only and pull-based; Reader.md never writes back to the remote.