2026.08.20gpui and the Mail Client Problem: A Text Field Costs 778 Lines28 min read The same event, two boundaries Two columns on a shared five-row grid, tracing the same event — a message landing in the mailbox while the user scrolls the thread list. Left column, Tauri or Electron: a sync task in the Rust core owns the store and the socket; the envelope is serialised to JSON, which is the only wire format the event system offers; the payload crosses into the WebView as evaluated JavaScript; a listener rebuilds the row, producing a second copy of the same data on the JavaScript heap; and a virtual list finally writes it into the DOM of WebView2, WKWebView or WebKitGTK depending on the user's operating system. Right column, gpui: the sync task runs on the background executor inside the same crate and the same address space; cx.spawn hops back to the main thread with an AsyncApp held across the await; store.update leases the state out, mutates it and returns it; cx.notify queues an effect that is flushed after the update completes; and the uniform list paints only the visible range on the next GPU frame. The left path buys a serialiser and a runtime you do not own, but gets a text field, a table and accessibility for free. The right path is a function call, and a design system you now maintain yourself. The same event, two boundaries a message lands in the mailbox while the user is scrolling the thread list Tauri / Electron sync task, Rust core owns the store and the socket serialise the envelope JSON — the only wire formatevents "are always JSON strings" cross into the WebView payload arrives as evaluated JS listener rebuilds the row a second copy on the JS heap virtual list, then DOM WebView2 / WKWebView / WebKitGTK gpui sync task, background executor same crate, same address space cx.spawn back to the main thread AsyncApp held across the await store.update(cx, ..) state leased out, mutated, returned cx.notify() effect queued, flushed after update uniform_list, next frame visible range only, painted by the GPU left: a serialiser, and a runtime you do not own right: a function call, and a design system you now maintain the left column ships a text field today; the right one charges 778 lines