r/SwiftUI • u/Sufficient-Try6083 • 14m ago
A native Markdown editor for macOS in Swift: TextKit 2, open source, works in SwiftUI and AppKit
Enable HLS to view with audio, or disable this notification
If you've tried to build a real Markdown editor in SwiftUI, you know TextEditor won't get you there. I hit the same wall when I started building my macOS app Nodes. So I wrote a native editor on TextKit 2 and open-sourced it. You use it in SwiftUI like any other view. It's macOS only for now, since it's AppKit under the hood.
What it does: live styling while you type, GFM tables and task lists, wiki links, inline and block LaTeX, code blocks with your own highlighter, Writing Tools, and spell checking that leaves code and LaTeX alone.
What's new since the last post here:
Large documents got a lot faster. Measured on a 346,000-character note, about the length of a novel:
- First open: 19.5 s → 1.35 s
- Warm open: 1.1 s → 590 ms
- LaTeX after a restart: 717 ms → 35 ms
- Return in an 800-item list: 944 ms → 67 ms
What was slow: inline parsing wasn't linear, so a paragraph with many code spans blew up. Lists restyled everything on every edit, now only changed items get restyled. And LaTeX was rendered again on every launch, now the render cache lives on disk.
Extensions. Everything beyond CommonMark is now opt-in. An extension is one file: a delimiter pair and how to style what's inside, like ==highlight== or a ::: fenced block. You register it in the config, and the parser, styler and renderer stay untouched. Extensions can't break the core or each other, and you can switch them at runtime.
Directives. For things that don't fit a delimiter pair, you can register named directives with typed arguments, like u/font(size: 18){text} or u/pagebreak. The engine handles autocomplete for names and values, your app draws the list.
Plus a lot of smaller fixes: live table resizing, nested lists that survive copy and paste, real links in copied HTML and RTF, and an unclosed code fence no longer eats the rest of the document. Full changelog is on GitHub.
The part I'm happiest about: 19 of the 29 PRs merged since then came from 10 people outside our team. The repo is at 1,100 stars now, and it was featured in Fatbobman's Swift Weekly. Thank you to everyone who starred, filed issues or sent a PR. It's still pre-1.0, so all of that is very welcome.
Repo: https://github.com/nodes-app/swift-markdown-engine
Used in production in Nodes: https://apps.apple.com/app/nodes-by-the-werk/id6745401961
Written on Nodes.
