Engineering
Our Rust UI take: what two days of native Velta taught us
· 5 min read
We built a working Velta client for Android in Rust — no WebView, no browser engine — and ran it on a mid-range phone next to the web app. Then we put our Android effort back into the Kotlin client. Both halves of that sentence are good news; this is the take.
Why we tried it
The Velta app you use on Windows, macOS and Linux is one build-less web UI wrapped in a system WebView, with the Delta Chat messaging core linked in-process. That shape has served well — but the pull of a native Rust UI is obvious: drop the WebView entirely, keep the core in-process, and share one user interface across every platform. A Rust UI toolkit (Masonry) with a working Android story exists, so we gave it a real shot: not a sketch, a client. Chat list with unread pills, chat view with day separators and quotes, a composer that rides the keyboard, swipe gestures, live incoming messages, links and invites — all rendered in Rust, booted on a phone.
What it proved
The architecture question is answered, and the answer is yes. Cold start to first frame: 157 ms on the phone, against 184 ms for the web app on the same device. Memory within noise of the web app (~126 MB vs ~113 MB — both carry the full messaging core in-process, which is why they sit so close). A chat list rebuild takes 3–13 ms; incoming messages land while you watch. Nothing about native performance scared us off, and the numbers are worth having: whichever UI ships, the core belongs in the process.
Where the bill came due
A UI toolkit draws. Everything a phone actually does around the drawing is yours to build, and the itemized list grew faster than the feature list. Copy and paste: a hand-written bridge into the platform clipboard service. The soft keyboard: a poller thread reading window insets, because the activity backend ignores the resize event. Typed text: a mirror of the input buffer, because the events never arrive. Scrolling: a gesture bridge. Text selection: a patched copy of the toolkit we vendor and maintain. One uncleared platform exception took the whole app down — once was enough to see the pattern.
The renderers told the same story from a different angle. Vello's GPU path deadlocks outright on Adreno-class phones. The hybrid path draws no color emoji — a dealbreaker for a messenger, where an emoji is content, not decoration. Skia met the full requirement set and carried a working liquid-glass prototype. And then we learned the punchline: Android's own platform shaders do displacement maps and blur natively. The effect we spent a day forking a rendering stack to get is a built-in on the platform we were leaving.
What remained was the honest mountain: notifications, attachment picking, share intents, accessibility, push, background sync — each one another bridge like the ones above, each one a new crash class. For a project with one maintainer, that math does not close.
The decision
The Kotlin client (Jetpack Compose, the same Delta Chat core in process) is back in active work, as a work in progress. The architecture we validated carries over whole; there the platform layer is the operating system's, not our code. It already carries encrypted-at-rest storage with a biometric lock, QR onboarding, relay management, account switching, attachments, reactions and background sync. Meanwhile the Tauri app stays the Android app that ships, and desktop keeps the web UI. The Rust client stays around as a lab: a place where renderer experiments cost an afternoon instead of a release.
What we keep
- The numbers — the core-in-process architecture is proven, with measurements to point at.
- The renderer verdicts — written down, with repro steps, so nobody re-litigates them from scratch.
- Design with receipts — Velta Prism (the person colors) and the fingerprint identity matrix now exist as parity-tested algorithms shared bit-for-bit between the web UI and the lab; the same name always produces the same colors, pinned by tests on both sides.
- Gratitude — Masonry and the vello family are promising and moving fast. Our verdict is about one maintainer's budget and a shipping deadline, not about the stacks; the lab will keep playing with them.
The native Android client is the work now. The next thing Android users should notice is not a new renderer — it is notifications, attachments and accessibility that simply work, because the platform provides them.