A fast, native macOS Markdown editor and reader.
No Electron — just Swift, SwiftUI, and AppKit.
Screen.Recording.2026-08-26.at.23.06.54.mp4
- Download the latest
.dmgfrom Releases - Open it and drag Markfops into Applications
- First launch: macOS will warn that the app is unidentified. Open System Settings → Privacy & Security, scroll down, and click Open Anyway
Requires macOS 14 (Sonoma) or later. Markfops checks for its own updates from then on.
- Real Markdown — full GitHub Flavored Markdown: tables, task lists, strikethrough, fenced code, autolinks
- Edit or preview any tab with
⌘⇧P, with syntax highlighting while you write - Tabs and windows that behave like macOS expects — drag tabs between windows, or tear one off into its own
- Sidebar with table of contents — expand any document to jump straight to a heading
- Your files stay yours — plain
.mdon disk, drag-and-drop to open, proxy icon in the title bar, PDF export - Light and dark preview that follows your system appearance
- Four languages — English, 한국어, 日本語, 简体中文
| Action | Action | ||
|---|---|---|---|
| New document | ⌘N | Find | ⌘F |
| New tab | ⌘T | Find & Replace | ⌘⌥F |
| New window | ⌘⇧N | Bold | ⌘B |
| Open file | ⌘O | Italic | ⌘I |
| Save | ⌘S | Inline code | ⌘⌥K |
| Save As | ⌘⇧S | Undo / Redo | ⌘Z / ⌘⇧Z |
| Close tab | ⌘W | Next / previous tab | ⌘⇧] / ⌘⇧[ |
| Toggle edit / preview | ⌘⇧P | Preferences | ⌘, |
git clone https://github.com/LPFchan/Markfops.git
cd Markfops
xcodegen generate
open Markfops.xcodeproj # then ⌘RNeeds Xcode 16+. The first build resolves Swift packages, so you'll want an internet connection.
Project layout and tech stack
Markfops/
├── App/ — Entry point, AppDelegate
├── Diagnostics/ — Instruments signposts for performance profiling
├── State/ — Document, DocumentStore, EditMode, HeadingNode
├── Views/ — SwiftUI views (sidebar, tab bar, editor container…)
├── Editor/ — NSTextView subclass + syntax highlighter
├── Renderer/ — cmark-gfm HTML renderer + HTML template
├── Parsing/ — Heading parser (TOC + favicon letter)
├── Commands/ — Keyboard shortcuts via CommandMenu
└── Resources/ — CSS stylesheets, asset catalog, localizations
| Layer | Technology |
|---|---|
| UI | SwiftUI + AppKit bridging |
| Markdown parsing | libcmark_gfm |
| Preview | WKWebView + custom CSS |
| Editor | NSTextView (TextKit 2) with a custom syntax highlighter |
| State | @Observable |
| Tab ordering | OrderedDictionary from swift-collections |
| Updates | Sparkle 2 |
Profiling tab switches
The generated Markfops scheme profiles the Debug configuration so Instruments can load Sparkle under local ad-hoc signing. Archive builds use Release.
- Product → Profile, select Blank, click Choose
- Add the Points of Interest or os_signpost instrument with +
- Record, switch between large documents a few times, stop
- Filter the signpost track for the
com.markfops.Markfopssubsystem
The outer Tab Switch interval measures selection through the next main-loop turn after the native surface updates. Nested intervals separate document activation, editor creation or update, editor configuration, large-text comparison and synchronization, syntax highlighting, preview cache checks, Markdown rendering, preview loading, and preview DOM updates. Surface Selected also reports whether the tab was already warm.
MIT — see LICENSE.