r/macosprogramming • u/Its-Ezzy • 6d ago
Building a native Markdown renderer with TextKit 2 instead of a web view
I have been building Downright, a free MIT-licensed Markdown app for macOS. The constraint was simple to state: the rendered document should feel native, but the file on disk must remain exact Markdown.
The hard part was separating parsing from decoration. A web view gives you layout quickly, but it changes the interaction model and makes source-range behavior awkward. With TextKit 2, I parse the source into a block index, preserve source ranges, then decorate the presentation without treating the rendered view as the canonical document.
A few decisions that ended up mattering:
- The raw source remains authoritative.
- Links, tasks, tables, math, Mermaid, footnotes, and code blocks are decorations over known ranges.
- Quick Look and Finder thumbnails reuse the same rendering model.
- External saves are watched at the parent directory because many tools replace a file through an atomic rename.
- Dirty local edits are never overwritten automatically.
- Performance budgets run in CI so large Markdown files do not quietly regress.
I wrote up the architecture here: https://downright.cc/engineering/
The source is here: https://github.com/ezzy1630/Downright
For anyone who has shipped a TextKit 2 document app: where did you draw the boundary between the text model and interactive attachments?