A clean, native markdown editor for macOS.
Download · Website · @Shpigford
Write with syntax highlighting, preview instantly, and get back to what matters. No Electron, no subscriptions, no bloat.
- Syntax highlighting — headings, bold, italic, links, code blocks, and more
- Instant preview — rendered GitHub Flavored Markdown, including Mermaid diagrams and KaTeX math
- Frontmatter support — YAML frontmatter is formatted cleanly in both editor and preview
- Side-by-side — edit and preview simultaneously with synchronized scrolling
- PDF export — export to PDF or print directly from the app
- Format shortcuts — Cmd+B, Cmd+I, Cmd+K for bold, italic, and links
- QuickLook — preview .md files right in Finder
- Light & Dark — follows system appearance or set manually
- macOS 14 (Sonoma) or later
- Xcode with command-line tools (
xcode-select --install) - Homebrew (brew.sh)
- xcodegen —
brew install xcodegen
Sparkle (auto-updates) and cmark-gfm (markdown rendering) are pulled automatically by Xcode via Swift Package Manager. No manual setup needed.
git clone https://github.com/Shpigford/clearly.git
cd clearly
brew install xcodegen # skip if already installed
xcodegen generate # generates Clearly.xcodeproj from project.yml
open Clearly.xcodeproj # opens in XcodeThen hit Cmd+R to build and run.
Note: The Xcode project is generated from
project.yml. If you changeproject.yml, re-runxcodegen generate. Don't edit the.xcodeprojdirectly.
xcodebuild -scheme Clearly -configuration Debug buildClearly/
├── ClearlyApp.swift # @main entry — DocumentGroup + menu commands (⌘1/⌘2)
├── MarkdownDocument.swift # FileDocument conformance for reading/writing .md files
├── ContentView.swift # Mode picker toolbar, switches Editor ↔ Preview
├── EditorView.swift # NSViewRepresentable wrapping NSTextView
├── MarkdownSyntaxHighlighter.swift # Regex-based highlighting via NSTextStorageDelegate
├── PreviewView.swift # NSViewRepresentable wrapping WKWebView
├── Theme.swift # Centralized colors (light/dark) and font constants
└── Info.plist # Supported file types, Sparkle config
ClearlyQuickLook/
├── PreviewViewController.swift # QLPreviewProvider for Finder previews
└── Info.plist # Extension config (NSExtensionAttributes)
Shared/
├── MarkdownRenderer.swift # cmark-gfm wrapper — GFM → HTML
└── PreviewCSS.swift # CSS shared by in-app preview and QuickLook
website/ # Static marketing site (HTML/CSS), deployed to clearly.md
scripts/ # Release pipeline (release.sh)
project.yml # xcodegen config — source of truth for Xcode project settings
ExportOptions.plist # Developer ID export config for release builds
SwiftUI + AppKit, document-based app with two modes.
ClearlyAppcreates aDocumentGroupwithMarkdownDocument(handles.mdfile I/O)ContentViewrenders a toolbar mode picker and switches betweenEditorViewandPreviewView- Menu commands (⌘1 Editor, ⌘2 Preview) use
FocusedValueKeyto communicate across the responder chain
The editor wraps AppKit's NSTextView via NSViewRepresentable — not SwiftUI's TextEditor. This is intentional: it provides native undo/redo, the system find panel (⌘F), and NSTextStorageDelegate-based syntax highlighting that runs on every keystroke.
MarkdownSyntaxHighlighter applies regex patterns for headings, bold, italic, code blocks, links, blockquotes, and lists. Code blocks are matched first to prevent inner highlighting.
PreviewView wraps WKWebView and renders the full HTML preview using MarkdownRenderer (cmark-gfm) styled with PreviewCSS.
- AppKit bridge —
NSTextViewoverTextEditorfor undo, find, andNSTextStorageDelegatesyntax highlighting - Dynamic theming — all colors go through
Theme.swiftwithNSColor(name:)for automatic light/dark resolution. Don't hardcode colors. - Shared code —
MarkdownRendererandPreviewCSScompile into both the main app and the QuickLook extension - No test suite — validate changes manually by building, running, and observing
Edit Clearly/Info.plist — add a new entry under CFBundleDocumentTypes with the UTI and file extension.
Edit Clearly/MarkdownSyntaxHighlighter.swift. Patterns are applied in order — code blocks first, then everything else. Add new regex patterns to the highlightAllMarkdown() method.
Edit Shared/PreviewCSS.swift. This CSS is used by both the in-app preview and QuickLook extension. Keep it in sync with Theme.swift colors.
Edit Clearly/Theme.swift. All colors use NSColor(name:) with dynamic light/dark providers. Update the corresponding CSS in PreviewCSS.swift to match.
No automated test suite. Validate manually:
- Build and run the app (Cmd+R)
- Open a
.mdfile and verify syntax highlighting - Switch to preview mode (⌘2) and verify rendered output
- Test QuickLook by selecting a
.mdfile in Finder and pressing Space - Check both light and dark mode
The marketing site is static HTML in website/, deployed to clearly.md.
website/index.html— landing page (version string on line 174)website/privacy.html— privacy policywebsite/appcast.xml— Sparkle auto-update feed (updated byscripts/release.sh)
This repo includes a CLAUDE.md file with full architecture context and Claude Code skills in .claude/skills/ for release automation and dev onboarding. If you're using Claude Code, these are picked up automatically.
MIT — see LICENSE.
