# Clearly: a native markdown editor for Mac and iOS

> Clearly is a Swift markdown editor for macOS and iOS that opens a .md file, gives you a native text view with syntax highlighting, and toggles to a preview rendered with cmark-gfm, KaTeX and Mermaid. It is on the Mac App Store and as a direct download, and the project publishes its Xcode project as a generated file so the YAML stays the source of truth.

**Shpigford/clearly** — Markdown editor for Mac, iOS and iPadOS

- Repository: https://github.com/Shpigford/clearly
- Website: https://clearly.md
- Stars: 1,198 · Forks: 78
- Language: Swift
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shpigford-clearly

## A text view, a web view, and nothing else

Clearly is a native markdown editor for Mac and iPhone, and the one-line summary of the product is the most direct description of the design: open a .md file, write with syntax highlighting, toggle to preview. Native macOS and iOS, no Electron, no subscriptions, no telemetry.

The absence of Electron is the whole point of the project, and it has consequences you can feel. The editor is a real NSTextView on the Mac and a real UITextView on iOS, so you get the system undo, the system find bar, the system text selection, the system accessibility and the system input methods. The preview is a WKWebView, so the rendered output is real HTML with real JavaScript libraries behind it, which is what makes the maths, the diagrams and the interactive elements possible.

The distribution is both App Store and direct. The Mac App Store listing is linked from the README, and there is a direct download of Clearly.dmg from the GitHub releases. The direct build gets the Sparkle auto-updater, and the App Store build does not need it, which is the usual split.

The site is clearly.md, the primary language is Swift, and the last push was on 2026-08-28, with the repository not archived and the current release v3.3.0 from 2026-08-23.

## The writing features

The writing section is the part that decides whether you can use it all day, and it is more than a syntax highlighter.

Syntax highlighting covers headings, bold, italic, links, code blocks and tables, and it happens as you type rather than when you stop. Format shortcuts handle the common cases, with command B for bold, command I for italic and command K for links, plus a full Format menu for the rest, which is the right compromise because a menu is slower but discoverable while a shortcut is fast but invisible.

Extended Markdown goes beyond the standard, with highlights written as double equals, superscript with a caret, subscript with a tilde, emoji shortcodes with a colon on each side, and a TOC tag that generates a table of contents. The document outline is a heading tree per document that you can click to jump, and find and replace is command F with regex and case-sensitive options, which is the same find bar as the system one, extended.

The scratchpad is the feature that is not really about Markdown at all. It is a menu-bar floating notes window with a global hotkey, so you can jot something down without opening the editor, and it is backed by the KeyboardShortcuts package, which is what makes the hotkey work while another application is in front.

The iOS side gets the same renderer and the same syntax highlighter, and opens any .md from the Files app, so the phone is a reader and a writer rather than a viewer.

## The preview pipeline, and what it does with your Markdown

The preview section lists the rendering features, and the order they happen in is the more interesting part.

GFM rendering covers tables, task lists, footnotes and strikethrough. KaTeX math handles inline and block equations. Mermaid diagrams are rendered from code blocks, so a flowchart or a sequence diagram in a fenced block becomes a picture. Code blocks are syntax-highlighted with line numbers, diff highlighting and one-click copy.

Callouts cover NOTE, TIP and WARNING plus fifteen or more other types, and they are foldable. And the preview is interactive, with checkboxes you can tick, images you can zoom, footnotes you can hover, and a double-click that jumps to the source in the editor.

The rendering order is documented as a post-processing pipeline: math, then highlight marks, then superscript and subscript, then emoji, then callouts, then the table of contents, then tables, and finally code highlighting. That order is not arbitrary, because each stage rewrites the HTML the previous stage produced, and the ones that can interfere are the ones that rewrite text nodes.

The callout implementation is worth a note. In most Markdown renderers a callout is a blockquote with a leading label, and the trick is recognising it in the tree after the Markdown has been parsed. Doing that as a post-processing pass over the rendered HTML, rather than by extending the parser, is what lets the same callout syntax work in both the web preview and the PDF export.

## Three targets, one shared core

The project structure section and the architecture section together describe a three target application with a shared package, and the arrangement is the interesting part.

There are three targets. Clearly is the Mac app, a DocumentGroup with a MarkdownDocument, an AppKit NSTextView editor and a WKWebView preview, both bridged with NSViewRepresentable, and a menu-bar MenuBarExtra for the floating scratchpads. Clearly-iOS is the same document model on the phone, with a UIKit UITextView editor and a WKWebView preview bridged with UIViewRepresentable, and the system Files browser as the entry point. ClearlyQuickLook is the Finder extension that previews .md files when you press Space, and it shares the MarkdownRenderer from the core package.

The shared code lives in a local SwiftPM package, Packages/ClearlyCore, which is platform agnostic and split into Rendering for the renderer, the syntax highlighter, the theme and the mermaid, math and table support, State for the document, outline, find, jump-to-line and status bar state, Editor for image pasting and downloading, Diagnostics for the log and the bug report URL, Stats for word counts, and Platform for the font, colour and image type aliases that paper over the difference between AppKit and UIKit.

The app entry point is ClearlyApp.swift with a DocumentGroup and the menu commands, the document model is MarkdownDocument.swift, which is a FileDocument conformance shared between Mac and iOS, and the Shared/Resources directory holds the bundled JavaScript and CSS for KaTeX, Mermaid and Highlight.js plus a demo document.

## Why the editor is not SwiftUI

The architecture section has a Key Decisions list, and the first entry is the one that explains the whole editor design.

The editor wraps the platform text views, NSTextView on the Mac and UITextView on iOS, through NSViewRepresentable and UIViewRepresentable. The stated reasons are that this provides native undo and redo, the system find user interface, and NSTextStorageDelegate-based syntax highlighting on every keystroke.

Each of those three is a reason you would notice if it were missing. Undo in a custom text implementation is famously hard to get right, and the system implementation is already correct for every edge case the system has. The system find bar is the same. And the syntax highlighting through the text storage delegate is the standard way to colour text in a native text view, because it runs on the attributed string the view already manages rather than on a separate layer that has to stay in sync.

The iOS note is the sharpest technical statement in the README. iOS stays on TextKit 1 because TextKit 2 makes textStorage effectively dead, and a text storage delegate based highlighter has nothing to attach to if the storage is gone.

That is a real constraint and it is worth knowing before you judge the iOS build as old-fashioned. It is a consequence of choosing the delegate approach for highlighting on every keystroke.

## Dependencies, signing and the release pipeline

There are three dependencies and each is doing a specific job.

cmark-gfm turns GitHub Flavored Markdown into HTML. Sparkle provides the auto-updates, and the table notes that this is for direct distribution only, since the App Store has its own update mechanism. KeyboardShortcuts provides the global hotkey for the menu-bar scratchpad.

They are pulled automatically by Xcode through Swift Package Manager, so there is nothing to install by hand for them.

The release machinery is the other half of the repository, and it is a good example of a project that treats distribution as a first-class concern. There are three ExportOptions plists, one for the App Store, one for iOS and one for direct distribution, and the .env.example file holds the values the release pipeline reads: the Apple team identifier, the Apple ID, the signing identity name, and the App Store Connect API key identifier, issuer identifier and key file. The file also carries the notarytool command for notarisation, with the password passed as an argument.

The scripts/ directory holds the release pipeline, the website/ directory is a static site deployed to clearly.md, and the docs/ directory holds the documentation. There is also a CLAUDE.md at the root and a .claude/ directory, so the project carries agent instructions alongside the code, and a CHANGELOG.md and a separate CHANGELOG-iOS.md, which suggests the two apps do not ship in lockstep.

## Building it, and the generated Xcode project

The prerequisites are macOS 15, Sequoia, or later for the Mac app, iOS 17 or later for the phone app, Xcode 16 or later with the command line tools, Homebrew, and xcodegen.

The quick start is:

```bash
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 Xcode
```

Then you press command R to build and run.

The note under it is the one to internalise. The Xcode project is generated from project.yml, and if you change project.yml you should re-run xcodegen generate, and you should not edit the .xcodeproj directly. That is a deliberate choice: the YAML is the source of truth and the project file is a build artefact, which means a contributor's diff is a diff of the YAML rather than of a file Xcode rewrites in whatever order it likes.

There is a command line build as well, for the cases where you want a binary without opening the IDE:

```bash
xcodebuild -scheme Clearly -configuration Debug build
xcodebuild -scheme Clearly-iOS -destination 'generic/platform=iOS Simulator' build
```

The site is clearly.md, the author is Shpigford, and the licence is a custom one that GitHub cannot classify, so the LICENSE file in the repository is the text to read rather than the badge.

## Conclusion

Adopt Clearly if you write Markdown on a Mac or an iPhone and want an editor that feels like a native application rather than a web page in a wrapper, and you are willing to accept an Apple-only tool with a fast moving release train. Do not adopt it if you need a cross-platform editor, since there is no Windows or Linux build and no Electron fallback, and do not fork the Xcode project expecting it to stick, because it is generated. Before you start, install xcodegen and generate the project rather than opening a checked-in xcodeproj, and read the architecture section, which explains the AppKit and UIKit bridge and why the iOS build stays on TextKit 1.

## FAQ

### What is Clearly and what platforms does it support?

It is a native markdown editor for Mac and iPhone written in Swift, and the product is that you open a .md file, write with syntax highlighting and toggle to a preview. The Mac app needs macOS 15 or later and the iPhone app needs iOS 17 or later, and there is no Electron, no subscription and no telemetry.

### How do I build Clearly from source?

You need Xcode 16 or later, Homebrew and xcodegen. Clone the repository, run brew install xcodegen and xcodegen generate to produce Clearly.xcodeproj from project.yml, open it in Xcode and press command R. The project file is generated, so you should not edit it directly.

### What can the Clearly preview render?

GitHub Flavored Markdown including tables, task lists, footnotes and strikethrough, KaTeX maths, Mermaid diagrams from code blocks, syntax-highlighted code blocks with line numbers and diff highlighting, and foldable callouts of many types. The preview is interactive, with checkboxes, zoomable images, hoverable footnotes and a double-click to jump to the source.

### Why does Clearly use a native text view instead of SwiftUI?

Wrapping NSTextView on macOS and UITextView on iOS through the representable protocols gives native undo and redo, the system find interface and NSTextStorageDelegate-based syntax highlighting on every keystroke. The iOS app deliberately stays on TextKit 1 because TextKit 2 makes textStorage effectively dead.

### How is Clearly distributed and updated?

It is on the Mac App Store and as a direct download of Clearly.dmg from the GitHub releases, and the direct build uses Sparkle for auto-updates while the App Store build uses Apple's own mechanism. The repository holds ExportOptions plists for each channel and an .env.example with the Apple team, App Store Connect and notarisation values the release pipeline reads.

## Sources

- [Issues](https://github.com/Shpigford/clearly/issues)
- [Project website](https://clearly.md)
- [README](https://github.com/Shpigford/clearly/blob/main/README.md)
- [Releases](https://github.com/Shpigford/clearly/releases)
- [Shpigford/clearly on GitHub](https://github.com/Shpigford/clearly)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shpigford-clearly
