dive
Joined 14 years ago
Joined 14 years ago
But is not it strange that I would need 8 months & a "development is ongoing" mindset just to render Markdown (which is very secondary to the main app features, and mostly just a user convenience people expect in 2026) with a custom low-level solution, effectively playing hardcore engineer instead of building what I actually want to build?
Anyhow, my point is not that "it is impossible". My point in the article is that I understand why people choose web technologies over native for such things. They want to build products, not fight the system’s limitations.
But I think my opinionated point from the article still stands: if you need rich text & good typography without fighting the platform, then web technologies quickly become the pragmatic choice.
For my app, I will probably continue with WebKit. It is the most reasonable middle ground for now. But in this situation, it is tempting to jump to something with a stronger rendering engine, like Chromium instead of WebKit, and start using the huge ecosystem of tools that already work. For example, https://diffs.com is one of the most tempting parts for me. The awkward thing is that embedding WebKit & calling it a day does not feel like a clean native solution either. You lose many of the native things you get when rendering through SwiftUI primitives, but you also do not get the full power & ecosystem of a proper web stack. And that makes it much easier to understand why so many companies (good & bad) choose Electron.
From an engineering perspective, even the fact that you can avoid this controversial middle ground entirely & build the app around web technologies from the start makes sense. It is not just laziness or ignorance of native platforms. Sometimes it is simply the more consistent & logical architecture.
Skill issue, I guess. I even tried your SSTextView (which is a very nice piece of software, by the way), though it does fit here, but I tried to understand how wrong my TextKit2 implementation is. In my tests, the SSTextView performed a bit worse with p95 on the static markdown scroll test (70.20 ms vs 16.7 ms for per frame rendering). But it is clear from the traces that SSTextView just does too many things I do not need. At least, I had my confirmation that I am not completely wrong about TextKit.
- Static completed Markdown scrolling fails the new focused probe. Result: p95 18.86 ms vs 16.7 ms budget, max 232.49 ms.
- Long live Markdown/code update path also fails. Result: p95 59.33 ms vs 16.7 ms, max 75.94 ms. This is a separate but related stress case around large rich text surfaces during updates.
- Long-history scaling technically passes, but the numbers are not smooth-frame healthy: - 120 turns: total p95 21.35 ms - 500 turns: total p95 23.11 ms - 1000 turns: total p95 36.77 ms
Technically, it is not bad. However, it is a bit slower than my own solution & has similar performance gaps, mostly related to SwiftUI rather than the Textual implementation.
And yes, I agree: on macOS, WebKit is a native OS framework. In that sense, it is "native". But I think it also supports the broader point I was making: if you want to work with rich text, Markdown, selection, typography, and long-form formatted content properly, web technologies quickly become the only viable option. I am not saying that using WebKit for a Markdown view is wrong. Quite the opposite, it is probably the most reasonable option available. The problem is that the "native" solution here is still effectively a web-rendering solution. There is a cost. Each `WKWebView` brings a WebKit engine with its own performance & memory overhead. So you cannot just sprinkle `WKWebView` everywhere & pretend it is free native macOS component as any other. My frustration is mostly that this is the answer. For this kind of UI, SwiftUI / AppKit / TextKit still do not give you a clean, modern, composable path that feels better than "just use WebKit".
By "streaming" text, I mean a formatted text stream that has to be parsed, formatted, and appended on the fly - basically how every model/AI chat works now. And this is where `NSTextView` becomes tricky. It forces an interesting architectural choice: either go deeper into AppKit with `NSCollectionView`, custom cells, manual layout, etc., or fight the whole SwiftUI model by embedding something like `NSTextView` inside `LazyVStack` / SwiftUI views & then dealing with all the integration problems.
So I am not saying Cocoa / AppKit was always bad, or that `NSTextView` is useless. I am saying that for modern chat-style UI with incrementally rendered formatted text, it does not compose well with the rest of the modern Apple stack.
This is my pet project, a desktop app for working with xAI models & capabilities, so by "performance" I mostly mean "pleasant to use" (as it goes, simple & opinionated). Technically speaking, something like: stable FPS, no visible lags, and the ability to scroll smoothly while the model is streaming.
Regarding the parent comment: yes, memory is important, and I absolutely get the point. There should be a red line, for sure. But I will not sacrifice UX, productivity, and simple pleasure from using software just to save a few hundred megabytes of RAM (or even a few gigabytes) especially for an app I spend hours with behind the screen.
Memory consumption can & should be optimised with proper engineering for sure. As lags & inadequate performance in basic SDK-level primitives are much harder (impossible?) to fix from the outside.
- The app does not support Dynamic Type and instead uses steppers for font adjustments, which seem to stop at arbitrary values.
- It uses a custom web view for link previews.
- In many instances, it ignores safe areas.
When you say “native,” do you mean it is written in Swift, or is there more to it?
[0] https://github.com/Ranchero-Software/NetNewsWire/blob/941342...