RCN Initiative #46 · Cross-Platform GUI Desktop Apps · Research Brief

The Rust desktop GUI ecosystem, measured

Seven frameworks deep-dived against primary sources, eight comparable specifications built in each of them (56 apps), and the dependency trees compared by experiment round — to answer two questions: where exactly is the fragmentation, and how do you actually ship a cross-platform desktop app in Rust today?

core research 2026-07-07 · experiments reconciled through 2026-07-10 · apple m4 pro · rustc 1.96.1 · methodology & full reports: gui-ecosystem-research repo

The thesis

converging bottom-up

The ecosystem is consolidating from the bottom of the stack upward — faster than its reputation suggests. In the last 12 months: the principal reusable pure-Rust text stacks converged on HarfRust, Zed dropped its custom Linux GPU layer for wgpu, and Slint/Bevy/floem migrated to parley/fontique. AccessKit is now the de-facto native accessibility abstraction; iced and floem remain unintegrated, while gpui support is unreleased and currently disabled in Zed. What remains fragmented is the top: text layout, 2D renderers, widgets, and windowing forks.

1
shared pure-Rust shaping engine. HarfRust now shapes for cosmic-text, parley and egui; gpui macOS/Windows use OS engines (its tested 0.2.2 Linux path shaped via cosmic-text/rustybuzz); webviews use browser engines; rustybuzz remains maintained elsewhere.
4
text-layout stacks still maintained (cosmic-text, parley, epaint galley, gpui) — the flagship duplication.
6+
framework-side renderer families targeting a mix of wgpu, platform GPU APIs, OpenGL/Skia, and software — the least-shared layer.
1/29
among the 29 crates in all seven dependency trees, raw-window-handle is the sole cross-platform GUI-interoperability abstraction; the set also includes platform-specific GUI crates.

Duplication matrix

capability × framework · july 2026
shared crate in-house webview missing — dioxus shown as its default webview desktop; stable dioxus-native 0.7.9 uses classic AnyRender/Vello, while development main defaults toward Vello Hybrid; current blitz-shell has no Muda dependency
Capabilityicedeguigpuitaurixilemslintdioxus
Windowing winit winit in-houseper-platform taowinit fork winit winit+qt, linuxkms taowinit migration proposed
GPU / render backend wgpu wgpu Metal/D3Dtested 0.2.2: blade on linux; zed main: wgpu ‘26, unreleased webview wgpu backend-dependentOpenGL/wgpu/Skia/software webview
2D renderer iced_wgpu epaint in-house webview vello femtovg/skia/qt+ own software webviewblitz 0.7.9: classic Vello
Text shaping harfrustvia cosmic-text harfrustin epaint 0.35+ platformCoreText/DWrite; linux (0.2.2): cosmic-text/rustybuzz webview harfrustvia parley harfrustvia parley webview
Text layout cosmic-text galleyshapes RTL runs; no paragraph BiDi in-house webview parley parley webviewblitz: parley
Font fallback fontdbdormant since ‘24 bundled platformlinux (0.2.2): fontdb webview fontique fontique webview
Widget layout in-house in-house taffy CSS in-house DSL+ taffy (exp.) CSSblitz: taffy+stylo
Widgets in-house in-house low-level elementsno reusable 1st-party suite; gpui-component is 3rd-party HTML/JS in-house~15 views in-house HTML/JS
Accessibility missingdraft PR #3111 AccessKitschema required; eframe adapter default unreleasedmerged 2026-05 webview AccessKit AccessKitdefault on Winit desktop webview
IME winitsince 0.14 winit platformwindows rough webview winit winit webview
Styling / theming in-house in-house tailwind-like CSS in-house DSL CSS

Converging vs diverging

last 12 months

▲ Convergence wins

  • wgpu is the leading reusable native GPU layer in this sample — the stored 2026-07-07 tables record roughly 1.27k reverse dependencies but differ by one, and the raw response was not retained; Zed replaced Blade with wgpu on Linux (Feb ’26), and eframe flipped its default from glow.
  • HarfRust unified reusable pure-Rust shaping in <12 months — adopted by cosmic-text 0.15, parley 0.6, and epaint 0.35. Platform/browser shapers remain.
  • AccessKit is the de-facto a11y layer — egui (schema required; eframe adapter default), Slint (default on Winit desktop), xilem, Bevy, vizia, Blitz, GTK 4.18, and gpui main. Iced and floem remain; gpui is unreleased and Zed currently opts out.
  • taffy crossed framework lines — gpui, Blitz, floem, bevy_ui, Servo (CSS Grid), Slint (experimental). 8.9M downloads.
  • parley/fontique absorbing the text layer — Slint 1.14, floem, and Bevy 0.19 all defected from cosmic-text/fontdb within a year.

▼ Persistent divergence

  • 4 text-layout stacks — cosmic-text (System76) and parley (Linebender) both actively funded; egui’s parley attempt stalled on an API-model mismatch.
  • The tao/winit fork is widening — tao is frozen on winit’s pre-0.30 API while winit redesigns for 0.31; un-forking is blocked on wry’s WebKitGTK needs.
  • 6+ renderer families in the sample — they target wgpu, platform GPU APIs, OpenGL/Skia, and software; classic Vello remains alpha, while Vello Hybrid has been described as roughly beta.
  • The current tauri-apps Linux shell paths split on the GTK fault line — muda menubars need GTK windows, tray-icon needs a parallel GTK loop on winit, and global-hotkey itself is X11-only.
  • winit itself was mid-redesign at the snapshot — 0.31 beta had been open for roughly seven months and 21 days; one prolific contributor announced a hiatus citing burnout. This is a high-dependency layer, not the sample’s most-depended-on crate.

The four fragmentations, explained

plain language · full primer in report/30-primer.md

A GUI framework is a tower of layers: window (winit opens the window and feeds you input) → GPU (wgpu turns one API into Metal/Vulkan/DX12) → 2D renderer (turns “rounded rect with shadow” into GPU work or pixels) → text (find fonts → shape glyphs → lay out lines) → layout (taffy computes flexbox math) → a11y (AccessKit feeds screen readers) → widgets. Several lower-layer abstractions are increasingly shared; these four stories are where sharing still breaks down.

1 · Four text-layout stacks the flagship duplication

Text is a pipeline: discover fonts → shape glyphs → lay out lines. The bottom stage just consolidated — HarfRust (the HarfBuzz org’s official Rust port) now shapes for cosmic-text, parley and egui. But the layout stage — line breaking, wrapping, bidirectional text, rich text, caret/editing semantics; the genuinely expensive part — still exists four times:

StackOwnerUsed byKnown holes
cosmic-textSystem76 (for COSMIC)iced, COSMIC, gpui-on-Linuxfallback via dormant fontdb
parleyLinebenderxilem, Slint, Blitz, Bevy, floemegui adoption stalled on API mismatch
epaint “galley”egui, in-houseegui onlyno paragraph-level BiDi reordering; no color emoji
line_layoutZed, in-housegpui onlyquality differs per OS (platform shapers)

Why it persists: both leading stacks have sustained institutional contributors—System76 employees on cosmic-text, and a mix of grants and employer-backed contributors around Linebender—so both remain active. egui tried adopting parley (egui#5784) and hit a real architecture mismatch: parley wants to own “a rectangle to fill with text”; immediate-mode egui re-derives layout every frame. Iced adopted cosmic-text in 2023; the retained primary sources establish the adoption, not why it was chosen over Parley.

Why you care: four stacks means four independent sets of text bugs. egui shapes individual Arabic/Hebrew runs but cannot reorder multiword or mixed-direction paragraphs correctly (egui#1016); Slint's run reordering and tested selection work, while explicit base direction, UI mirroring, and codepoint-oriented backspace remain gaps. Momentum favors parley (3 frameworks migrated in 12 months) but cosmic-text won’t vanish while COSMIC ships on it.

2 · Six-plus framework-side renderer families the least-shared layer

Reusable native stacks increasingly share wgpu, but renderer implementations still target a mix of wgpu, platform GPU APIs, OpenGL/Skia, and CPU software. In this sample the framework-side layer includes vello (Linebender, GPU compute), epaint (egui, CPU tessellation), iced_wgpu, femtovg (Slint default), Skia bindings (Slint premium/freya), and gpui’s shader pipeline (“render like a videogame”, one shader per primitive).

Why it persists: genuinely different philosophies (compute-shader vector rendering vs tessellation vs SDF shaders), plus Slint’s need to run on GPU-less microcontrollers. Vello is one prospective shared renderer, alongside reusable Skia, FemtoVG, and tiny-skia paths; classic Vello is alpha and only Hybrid has been described as roughly beta.

Why you care: the six-plus renderer families duplicate some anti-aliasing, clipping, glyph-atlas, and GPU-driver work, but this audit did not quantify a multiplier. This layer consolidates last, if ever — the realistic near-term win is sharing the bricks (egui already adopted vello_cpu for glyph rasterization) rather than whole renderers.

3 · The widening tao/winit fork two windowing layers, drifting

In 2021 Tauri forked winit into tao because it needed native menus/tray and — decisively — GTK-hosted windows on Linux, since WebKitGTK (Wry/Tauri’s supported Linux system-webview backend) can only render inside GTK containers. Menus and tray have since been extracted into winit-compatible crates (muda, tray-icon), removing part of the fork’s original rationale — but the GTK constraint remains (tao#509: “running webkitgtk outside of gtk is not fun or not even possible”).

The drift: tao is frozen on winit’s pre-0.30 closure API while winit’s 0.31 redesign moved away from it (historically tracked in the now-closed winit#3367). Divergence can require parallel maintenance, but this audit did not establish that every platform fix is duplicated. Dioxus 0.7.9 still ships Tao/Wry; a winit migration is proposed in open dioxus#2706. Tauri v3 planning targets GTK4, not an un-fork. The structural fix — a windowing-agnostic wry (wry#1014) or winit GTK embedding — remains unshipped; this audit found no dedicated public funding source for it.

4 · The GTK fault line in Linux shell integration GTK/X11 coupling in common tauri-apps paths

Specific Linux paths in the common tauri-apps shell crates hit a GTK/X11 boundary: muda’s Linux menubar API requires a gtk::Window, so it cannot attach that menubar to a plain winit window; tray-icon’s winit path requires a second GTK event loop on a parallel thread; and global-hotkey’s Linux backend is X11-only. Wayland portal support already exists in Rust through ashpd, while ksni implements StatusNotifierItem. winit itself has no menu/tray API (winit#403, open since 2018).

Why you care: this specific integration gap contributes to native-GPU Rust apps feeling “not quite a desktop app” on Linux. It’s not impossible — the remaining opportunity is to integrate existing portal/SNI/DBusMenu implementations into maintained, winit-compatible shell facades. That shared integration would benefit every winit-based framework.

5 · Bonus: AccessKit’s concentrated authorship and public-support record the a11y linchpin

What it is: screen readers don’t see pixels — they need a semantic tree (“a button named Add, focused”), and every OS has a different ancient API for it. AccessKit defines one Rust tree format with adapters for Windows UI Automation, macOS NSAccessibility, Linux AT-SPI, Android and iOS. No comparable cross-toolkit Rust abstraction was found in this audit; egui, Slint, xilem, Bevy, vizia, Blitz, GPUI (since May ’26), and GTK 4.18 all integrate it, although Zed currently opts out of GPUI’s path.

Recent-author concentration: public commit attribution in the dated snapshot is dominated by Matt Campbell and Arnold Loubriat. That is a continuity heuristic, not a measured probability of project collapse. STF: the Sovereign Tech Fund, a German federal program for critical open-source infrastructure, funded AccessKit’s Linux work through a GNOME Foundation contract in 2023–24 (GNOME STF report). That 2023–24 project was described as mostly wrapped up by Apr 2025. This audit found no later direct institutional AccessKit grant; visible personal support includes GitHub Sponsors.

Why you care: the ecosystem standardized on a project with concentrated recent authorship and no later direct institutional grant identified in this audit — and the remaining gaps (a web/canvas adapter, deeper text-editing semantics, and the prototype-stage Wayland a11y stack “Newton”) are long-running infrastructure work for which sustained support could materially help.

The load-bearing crates

who actually carries the ecosystem · verified 2026-07-07

The shared infrastructure under the sampled frameworks, ranked by an explicitly interpretive sustainability assessment. The table contains 21 entries; 15 are rated amber/red. “Author concentration” is a heuristic derived from dated public commit attribution, not a measured probability of collapse, and “none found” means no public direct funding source was identified—not proof that a contributor is unpaid. Exact reverse-dependency, sponsor, and search-result counts are dated snapshot observations whose raw query responses were not retained. Full sourced table: report/data/load-bearing-crates.md.

red — higher observed continuity risk amber — concentrated / monitor green — broader or institution-backed support
CrateWhat it isAuthor-concentration indicatorPublic support evidenceLast releaseObserved signal / interpretationAssessment
fontdbfinds fonts installed on the systemno sampled activityno public direct source or announced successor foundOct 202421-month release gap; used under Iced/COSMIC/Zed-Linux font resolutionred
apple-codesignRust-native signing & notarization from non-Mac CIhighGitHub Sponsors (8 public at snapshot)Nov 2024no release in 19 months and 69 open issues; principal open-source Rust-native path foundred
winitopens windows, delivers keyboard/mouse/IME events everywherehighno direct institutional source found; personal sponsors visibleMar 20260.31 redesign in beta for roughly 7 months and 21 days; a prolific contributor announced a hiatus citing burnout; 1,225 reverse deps recorded at snapshotamber
taffyCSS flexbox/grid layout math as a libraryhighno public direct source foundJul 2026recent authorship concentrated in one maintainer under Zed, Bevy, Servo, Blitz, Slintamber
accesskitthe screen-reader bridge for Rust toolkits (+ GTK 4.18)high2023–24 STF/GNOME project mostly wrapped up; personal sponsors visibleJun 2026recent work concentrated in two people; no later direct institutional grant foundamber
cosmic-texttext layout engine (the Iced/COSMIC one)highSystem76 employment supports the maintainersApr 2026active, with support concentrated in one companyamber
swashrasterizes shaped glyphs into pixelshighmaintainer employment is separate from a direct project grantJun 2026recent public commits concentrated; compatibility work continuesamber
taoTauri’s winit fork (GTK-hosted windows for Linux webview)highTauri umbrella / CrabNebula involvementMay 2026recent authorship concentrated; remains on the pre-0.30 winit APIamber
mudanative menu bars & context menushighTauri umbrella; no direct source foundJun 2026recent authorship concentrated; Linux menubars require a GTK windowamber
tray-iconsystem tray iconshighTauri umbrella; no direct source foundJun 2026recent authorship concentrated; winit Linux path requires a parallel GTK loopamber
global-hotkeysystem-wide keyboard shortcutshigh / low-volumeTauri umbrella; no direct source foundMay 20266 commits in 12 months; its Linux backend is X11-only (ashpd exposes the portal separately)amber
arboardclipboard read/writehighmaintained in the 1Password organizationAug 2025~10.5-month release gap against 1,052 reverse deps at snapshotamber
rfdnative open/save file dialogshighno public direct source found; 0 public sponsors at snapshotJan 2026active, with recent public work concentrated in one maintainer; 479 reverse depsamber
notify-rustdesktop notificationshighno public direct source foundJun 2026active across three platforms, with recent authorship concentratedamber
softbufferCPU pixel buffer onto a window (software rendering)highno public direct source foundDec 202576 of roughly 84 commits in the audited year attributed to one authoramber
wgpuone GPU API → Metal/Vulkan/DX12/WebGPUlowerMozilla employs core maintainers for Firefox WebGPUJul 2026broad employer-backed contributor set in this comparisongreen
harfrustthe text shaper (ligatures, Arabic, kerning)moderateGoogle Fonts–backed, HarfBuzz orgJul 2026active with upstream/institutional backinggreen
parley + fontiquetext layout engine + font fallback (the Linebender one)lowertwo active NLnet grants (through Aug 2026) + Canva contributorJun 2026active; time-bounded grant deadlines are a continuity considerationgreen
wryembeds the OS webview (the Tauri/Dioxus renderer)lowerTauri programme; CrabNebula employs a maintainerMay 2026multiple active contributors in the sampled windowgreen
tiny-skiaCPU 2D renderer (iced’s software fallback)lowerLinebender stewardship (post-handoff)Feb 2026post-handoff release shipped; activity remains modestgreen
raw-window-handlethe universal window-handle socket between cratesmoderaterust-windowing umbrella; no direct project source foundMay 2024stable API with low release activity (78M downloads at snapshot)green

One app, seven frameworks

identical spec · same machine · serial builds

A todo app (text input, Enter shortcut, per-row delete, live counter, scrolling) built idiomatically in each framework, versions pinned. All seven compiled and survived the launch check; later inspection observed their windows, and the implementations cover the source-level spec (GPUI exposes low-level elements and a hand-built input example but no reusable first-party high-level input widget, so this app approximated text input). On this M4 Pro, these seven small apps each clean-built in under a minute from a warm registry and empty target directory; that is not a general large-application ranking.

Clean release build

seconds · cargo clean → build --release
iced
22 s
egui
27 s
xilem
28 s
tauri
36 s
dioxus
40 s
slint
42 s
gpui
56 s
Incremental rebuilds: 1–4 s everywhere except tauri (10 s — build-script re-validation).

Binary size, stripped

MiB · release binary after strip
gpui
4.3
dioxus
4.9
tauri
6.4
iced
8.5
xilem
9.7
egui
10.5
slint
13.2
A small webview executable externalizes its renderer. In the controlled live-dashboard run, webviews used 208–211 MiB including helpers versus 79–109 MiB for native-rendered apps.

Dependency tree

unique crate names in cargo tree
iced
140
xilem
143
egui
156
tauri
204
dioxus
279
slint
302
gpui
391
Of 29 crate names common to all seven trees, 13 resolve to multiple versions across apps — version skew is a measurable fragmentation cost.

Recorded source size

lines · rust + markup/JS where applicable
iced
74
xilem
81
dioxus
90
slint
94
egui
168
tauri
208
gpui
230
GPUI is high because its reusable first-party high-level text-input/widget suite is incomplete, despite low-level elements and a hand-built input example. Counts are Rust + HTML/JS/CSS or Slint DSL and exclude JSON/TOML config, but include verification hooks embedded in source; they are not pure production-only LoC. Tauri therefore shows 208 here.

The interactivity curve

round 2 · two interaction-heavy apps × seven frameworks

Round 2 tested what production apps are made of: drag-and-drop, live data, custom charts, hover interactions, inline editing, animation. Two more apps per framework — “Pulse” (live metrics dashboard: draggable card grid, 10–60 Hz data, hover-tooltip chart) and “Board” (kanban: cross-column DnD, drop indicators, double-click edit). All 14 built and survived the scripted launch check, and later inspection observed their windows; interaction evidence ranges from source/API paths through retained app tests as marked per capability. Full data: report/11-interactive-results.md + per-app FRICTION.md.

built-in assembled from primitives hand-rolled approximated
Capabilityicedeguigpuitaurixilemslintdioxus
Charts + sparklines hand-rolled egui_plot hand-rolled Canvas2D hand-rolled Path strings SVG in RSX
Chart hover + tooltip hand-rolled 1 line hand-rolled hand-rolled hand-rolled assembled assembled
DnD: grid reorder hand-rolled egui_dnd native DnD HTML5+math hand-rolled hand-rolled hand-rolled
DnD: cross-column hand-rolled hand-rolled native DnD hand-rolled hand-rolled DragArea 1.17 hand-rolled
Drag ghost assembled assembled built-in free (HTML5) assembled hand-rolled hand-rolled
Live data 10–60 Hz built-in² idiom spawn loop events task view Timer tokio DIY
Inline edit (dbl-click) assembled assembled own editor assembled own editor assembled assembled
Animate reorder/drop snaps¹ tweens settle only CSS FLIP snaps¹ animate x,y CSS settle

¹ The sample has no shared automatic FLIP/position-transition abstraction: stock iced/xilem layouts snap, while the implementations used egui tweens, hand-built CSS FLIP, or explicit Slint x/y animation. ² iced’s time::every needs a non-default executor feature; the compile error gives no hint.

Code for both apps

total LoC (Rust + markup/JS) · same two specs
dioxus
936
egui
1038
slint
1166
tauri
1199
gpui
1248
iced
1394
xilem
2393
These totals include different amounts of verification/config code; publish production and harness LoC separately before treating the ranking as framework overhead.

CPU while live at 10 Hz

avg % of one core · one 30 s observation · incl. webview helpers · 2026-07-10 rerun reproduced ±≈1 pp (retained); occluded/backgrounded runs read far lower
iced
3.5%
gpui
6.8%
slint
9.2%
egui
9.6%
xilem
9.9%
dioxus
11.9%
tauri
14.0%
The immediate-mode CPU-tax folklore didn’t materialize in this live-dashboard sample: egui’s reactive scheduler repaints at the tick rate. No controlled board-idle dataset was retained.

Memory while live

max RSS, MiB · incl. WebKit helper processes
gpui
79
iced
95
slint
95
xilem
106
egui
109
dioxus
208
tauri
211
Two clean tiers in this run: native-rendered ≈ 79–109 MiB, webview 208–211 MiB for the identical live dashboard.

What the round taught

cross-cutting findings
Six implementations hand-rolled charts — the experiment used only egui’s helper, although current Iced- and GPUI-compatible chart crates also exist with uneven maturity.
DnD support differs by layer — gpui and Slint had strong vendor primitives; other implementations used framework events, compatible helpers, or custom pointer state.
The text-input gap compounds — gpui/xilem hand-rolled editors just for double-click edit.
Several implementations exposed concrete traps — wry’s dragDropEnabled eating drag events, egui drag sources making child buttons inert, masonry’s last-wins capture, Dioxus events lacking geometry, and iced’s input eating Escape. The retained list does not establish one trap for every framework.
Documentation observation — all 7 implementations required reading vendored crate source, and several pre-current tutorials were stale; this is an observation from the study, not a universal expiry rule.

The “hard parts,” measured

round 3 · OS shell integration · “Tray Notes” × 7 (macOS)

One quick-note app per framework exercising everything AROUND the window: tray, global hotkey, native menubar, dialogs, clipboard (text + image), Finder file-drop, notifications, live dark mode, multi-window, close-to-tray. Zero implementation-level not-achievable cells on tested macOS — every framework exposed a viable path, although Finder drops and some notification results were source/API-level rather than real end-to-end observations. Full matrix + evidence notes: report/12-shell-integration-results.md.

built-in assembled (helper crates + glue) hand-rolled / workaround
Capabilityicedeguigpuitaurixilemslintdioxus
System trayassembledassembledassembledbuilt-inassembledDSL elementbuilt-in
Global hotkeyassembledassembledassembledpluginassembledassembledbuilt-in
Native menubarmuda¹muda¹built-inbuilt-inmuda¹DSL elementbuilt-in
Native dialogsrfdrfdbuilt-inpluginrfdrfdrfd
Clipboard imagearboardarboardbuilt-inpluginarboardarboardarboard
File drop (Finder)built-inbuilt-inbuilt-inbuilt-inworkaroundunstable featurebuilt-in
Notificationnotify-rustosascript²notify-rustpluginosascript²notify-rustnotify-rust
Dark mode (live)built-inbuilt-inbuilt-inbuilt-inhand-rolledbuilt-inbuilt-in
Close-to-traybuilt-inassembled³assembledbuilt-inassembledbuilt-inbuilt-in

¹ A trap reproduced in these 3 integrations: muda’s predefined Edit items silently swallow ⌘X/⌘C/⌘V before the framework’s own bindings — the standard Edit menu breaks paste app-wide. ² notify-rust was rejected after a reproducible frame-scheduling freeze in this egui/macOS configuration; delegate replacement is the leading inferred cause. ³ eframe never runs App::ui for hidden viewports — reopen logic must live elsewhere or the window can’t come back. Round upset: dioxus quietly matches Tauri here (tray, hotkey, menubar, multi-window, close-to-tray all built-in). Scope note: this is macOS; the Linux GTK fault line (muda menubars cannot attach to plain winit windows; global-hotkey is X11-only) stands as documented in the fragmentation stories.

One corpus, seven text stacks

round 3 · “Babel” · same 11 lines everywhere

The same multilingual corpus (Latin ligatures, Arabic/Hebrew BiDi, Chinese/Japanese/Korean, Devanagari, Thai, ZWJ emoji, one all-scripts line) rendered by every framework — the text-stack fragmentation made visible. Verification used screenshots plus OCR/glyph/caret diagnostics described in each FRICTION file. The seven screenshots are retained, but not every raw diagnostic output is; exact caret/OCR/mark counts and caption-specific interpretations therefore remain local observations rather than independently reproducible results. Full matrices incl. evidence levels and editing behavior: report/13-text-i18n-results.md.

The sharpest cross-stack finding is about editing, not rendering: Backspace over 👨‍👩‍👧‍👦 deletes the whole cluster in WebKit and gpui’s hand-rolled editor, shrinks it through valid smaller emoji in Slint (by design), and splits the cluster or leaves a dangling zero-width joiner in the tested iced, egui, and xilem editing paths. Those integrations lacked whole-cluster deletion out of the box; this does not establish that cosmic-text or Parley themselves lack grapheme editing. Egui also dropped 13 corpus combining marks; Slint showed one notdef mark and clipped tall stacks. macOS AX selected-text queries returned garbled RTL text for egui; actual screen-reader speech was not exercised, so assistive-technology impact remains an inference.

From binary to .dmg

round 3 · packaging the todo apps · macOS

All seven iteration-1 apps were bundled into launching DMGs containing ad-hoc-sealed .app bundles. The “packaging is the hard part” claim splits in two: the mechanical layer is nearly free — a revived cargo-bundle packaged all six non-Tauri frameworks with an identical 4-line stanza, under a minute each (and beat cargo-packager, the ecosystem’s “intended answer,” head-to-head in this run). The trust layer is the real cliff: with no identity configured none of the tested runs produced a distribution signature; cargo-bundle lacks signing while Tauri/cargo-packager support it when configured. The create-dmg flows failed repeatedly on this macOS 26 machine, while a plain hdiutil create fallback was more reliable. In the standard quarantined-distribution path tested here, spctl rejected all seven ad-hoc bundles as expected without Developer ID signing and notarization; Tauri, cargo-packager, and the principal Rust-native cross-platform implementation rcodesign automate parts of that workflow but cannot supply Apple credentials. Bundle sizes: 5.0 MiB (GPUI) → 14.7 MiB (Slint). Reliable app-attributed notification banners and dock behavior also benefit from a bundled, identified .app. Details: report/14-packaging-results.md.

Hardware, data, and async

round 4 · camera/mic · 100k-row grid · network — 21 more apps (macOS)

Round 4 tested the last untested dimensions: “Peek” (camera preview ≈30 fps, mic meter, audio, 200-image gallery), “Grid” (100k rows: virtualization, sort, filter, resize, selection), and “Fetcher” (debounce, streamed progress, and cancellation proven by a local server that logs client disconnects). All 21 apps built and ran. Full matrices with per-cell evidence labels: report/15-media-hardware-results.md, report/16-data-grid-results.md, and report/17-async-network-results.md.

Camera preview: observed CPU around 30 fps

% of one core · reported ps samples/ranges · paths and resolutions differ
dioxus
5–9%
gpui
~8%
tauri
4–12%
egui
~16%*
iced
~28%
slint
~34%
xilem
60–75%
The observed 4–75% range tracked different texture paths: the webviews used getUserMedia, GPUI used an undocumented public zero-copy surface path (the IOSurface is the Metal texture; NV12-only assert), and the other native paths re-uploaded RGBA frames. This is not a controlled ranking: resolutions and implementations differ, and only Dioxus retained a raw per-sample CPU CSV. *egui at 720p; iced/slint/xilem at 1080p. Tauri also deviated from the requested cpal/rodio path by using WebAudio/getUserMedia. Dioxus’s Rust-side alternative measured 4–6× its JS path for identical pixels.

What round 4 settled

condensed · details in reports 15–17
Computation was not the bottleneck in these tested grid apps — recorded filter/sort self-tests took roughly 1.5–19 ms, including several double-digit sorts. The timings used different queries, ordering, and measurement points, so they are not a controlled framework ranking. Among tested first-party options, egui_extras TableBuilder was the only suitable table basis: resizing was built in, while sorting and shift-selection were assembled in the app. Iced’s new table eagerly built 600k cell widgets in the inspected path, and Slint’s StandardTableView did not meet the chip or multi-selection parts of this spec. Xilem supplied stock virtualization but represented roughly 8,000 rows rather than the full 100,000; its table furniture was hand-rolled from Masonry widgets.
All seven cancel network requests for real (server-verified TCP aborts) — via seven different async architectures, none portable; drop-based cancellation composes wherever tokio is native or bridged.
One runtime-shaped trap per framework: iced’s default executor has no reactor (reqwest panics at runtime); ehttp’s default timeout kills long streams; gpui ships a null-only HttpClient trait; tauri’s webview fetch is CORS-blocked from tauri://localhost (the plugin fix bakes URL scopes at build time); xilem re-exports tokio without macros; slint’s spawn_local has an executor but no reactor; dioxus’s occluded windows park the whole task loop (3/6 ordinary runs, deterministic with always-on-top; 0.7.9) — in-flight downloads stop; wry has the fix, dioxus doesn’t plumb it.
TCC observation, scoped to this machine: four tests of unbundled cargo binaries launched from the same terminal inherited that terminal’s permission decision. This is not established as a universal macOS rule.
nokhwa 0.10.11 was not usable out of the box with the FaceTime camera on this host: the tested path encountered NV12 fourcc mapping, advertised-frame-rate, and patch-release compilation problems, and required source-level workarounds. This does not establish that nokhwa is generally broken on modern macOS.

Linux reality check

round 5 · Docker/Xvfb · software GPU · X11 · arm64 Debian 12

The macOS-built apps, rebuilt and run on Linux headlessly (lavapipe software Vulkan + llvmpipe GL, WebKitGTK 2.50.6 — one plausible CI configuration). All 11 tested apps compiled with zero source changes; the differences live entirely in the render path and the shell layer. Verbatim logs, screenshots, and probe sources retained. Full report: report/18-linux-reality-results.md.

Default render paths: egui, slint, tauri, dioxus just work; iced panics on software Vulkan (its shader needs an f16 capability lavapipe lacks — and it does NOT auto-fall-back to its own tiny-skia); xilem hard-aborts (uncatchable lavapipe/LLVM JIT bug in vello’s compute shaders); gpui silently renders nothing — Vulkan init succeeds, window maps, zero frames, zero diagnostics (root cause proven by a working probe, 2026-07-10: the event-loop hypothesis is refuted — the X socket is polled and read, and frames ARE rendered and submitted, but the X server rejects every present with BadMatch: a depth-24 PutImage blit onto gpui’s depth-32 ARGB window, silently swallowed; vkcube renders because it uses the default depth-24 visual). Software Vulkan is the fragile path — WGPU_BACKEND=gl rescued both wgpu failures.
WebKitGTK workarounds unnecessary in this environment: the DMABUF/compositing blank-window workarounds were tested and verified unnecessary on 2.50.6 in this Xvfb/llvmpipe environment for both webview apps (Tauri docs still recommend them for NVIDIA/driver-conflict setups — not evidence of general obsolescence).
The GTK fault line, confirmed live: the tested Muda API could not attach a menubar directly to a plain Winit window (E0277 retained); our macOS-written tray apps compiled unchanged on Linux and then panicked at launch in Muda’s first GTK call — build-only Linux CI passed while each tested launch died; tray failures without a GTK loop or without a StatusNotifier host are silent successes. global-hotkey’s X11 path works end-to-end.
Text travels better than the shell: iced-babel’s BiDi layout is visually/order-consistent with the macOS run (cosmic-text), CJK/Devanagari/Thai correct from Noto, CBDT color emoji works — but singleton emoji render monochrome (distro font-fallback ordering shadows Noto Color Emoji).

Framework verdicts

from the deep dives · versions tested

iced

0.14.0 · MIT
Enforced Elm architecture on winit + wgpu + cosmic-text. Leanest tree, fastest build, cleanest code for CRUD-shaped UIs. Powers COSMIC (via fork), Sniffnet, Halloy.
no a11y in stablehigh maintainer concentrationno built-in menus/tray14-mo release gap
Pick when you want structural discipline and can defer accessibility. COSMIC/Halloy use forks or master; Sniffnet ships stable Iced.

egui

0.35.0 · MIT/Apache
Immediate mode with reactive repaint. Changed shaping, font handling, and rasterization (harfrust + skrifa + vello_cpu) in ’26 while retaining galley layout. The schema used here requires AccessKit; platform adapters depend on the integration and features. Ships a headless a11y-tree test harness (kittest).
AccessKit adapter default via eframeno paragraph BiDibundled fonts by defaultRerun-backed
Pick when building tools, editors, debug UIs — 1 s incremental rebuild and the second-lowest round-two implementation LoC overall (lowest among the native-rendered implementations).

gpui

0.2.2 · Apache-2.0
Zed’s engine: hybrid retained/immediate, custom windowing, taffy layout, 120 fps discipline. Smallest binary in test. Core GPUI provides low-level elements and a hand-built input example; a reusable high-level suite is typically supplied by third-party gpui-component (Zed’s own ui crate is GPL).
a11y unreleased / Zed opted outcrates.io stalled 8.5 mono reusable 1st-party input$32M Series B, Aug ’25
Pick when performance is the product and the team can git-pin the zed monorepo.

tauri

2.11.5 · MIT/Apache
Rust core + system webviews by default (wry/tao); Windows installers can instead bundle fixed/offline WebView2. It offers first-party capability controls and configurable CSP, ~30 official plugins, and an integrated first-party runtime updater. Browser-grade text/IME and a strong a11y baseline when semantic HTML/ARIA are authored.
webview a11yiOS+AndroidWebKitGTK pain on LinuxCommons Conservancy
Pick when the team knows web tech or you need mobile + updater + plugins today. The Verso/Tauri integration is archived; Servo itself remains active.

xilem

0.4.0 · Apache-2.0
Linebender’s reactive framework on the converging stack: winit + vello + parley + AccessKit. Deep text semantics; no publicly documented shipping production Xilem app was found in this audit; ~15 views/widgets.
AccessKit deepalpharelease lags main 8 mopost-Google funding
Pick when experimenting with where the ecosystem is heading — several other stacks are adopting parts of the same foundation.

slint

1.17.1 · GPL/RF/paid
Compiled .slint DSL + live tooling; the only one of these seven with a documented MCU (264 kB RAM)-to-desktop target. Slint, Xilem, and Dioxus all recorded zero source-level SPEC-1 gaps. First-class declarative menus/tray; Fluent default since 1.16.
AccessKit default on Winit desktopattribution required (RF)DSL = 2nd languagerevenue-funded GmbH
Pick when designer-driven product UIs or embedded+desktop span; read the Royalty-Free license terms first.

dioxus

0.7.9 · MIT/Apache
React-like RSX + signals over the same Tao/Wry webview family as Tauri. Normal handlers avoid a user-authored invoke boundary, but VDOM events/mutations still cross a Rust↔webview bridge. Blitz is pre-alpha: stable dioxus-native 0.7.9 uses classic AnyRender/Vello, development main defaults toward Vello Hybrid, and current blitz-shell has no Muda dependency.
webview a11yexperimental subsecond hotpatchno Tauri-style security modelYC profile: Acquired
Pick when you want web ergonomics in Rust and accept a young stack. The CLI supports deep-link metadata, signing/notarization, and updater archives; no first-party runtime update client was found.

Choosing in five questions

the decision path, condensed
1 · Is accessibility a hard requirement this year?
Yes → Tauri/Dioxus (browser a11y tree), Slint on its default Winit desktop path, or egui through default eframe integration. Rules out iced and released gpui. Integration presence ≠ audited screen-reader compliance — prototype with VoiceOver/NVDA first.
2 · Does the team know and like HTML/CSS?
Yes → Tauri (JS-first team, security/plugins/updater) or Dioxus (all-Rust, React-like). No → native-GPU family.
3 · What shape is the app?
Forms-and-lists product → iced. Tool/editor/data-dense → egui. Designer-driven or embedded ambitions → Slint. Editor-class performance → gpui. Research bet → xilem.
4 · Mobile from the same codebase?
Documented iOS + Android paths today → Tauri, Dioxus, or Slint (Slint’s Rust iOS path uses Winit + Skia). Official Android-only is also available through egui/eframe; eframe does not document official iOS support. No mobile → all options open.
5 · Special contexts
GNOME-first → relm4/gtk4-rs · Qt shop → cxx-qt · audio plugins → vizia/baseview · MCU + desktop → Slint · tiny utility → fltk-rs.

Whatever you pick: prototype the riskiest screen first (not hello-world), pin versions exactly (several audited tutorials were stale; this was not universal), test Linux on Wayland + NVIDIA early, and budget real time for packaging, signing, and updates. Tauri has the most integrated first-party chain; other stacks assemble maintained bundlers, platform tools/rcodesign, and Velopack.

What a working group should fund

highest-leverage consolidation, priority order
  1. Finish the accessibility map: fund iced’s AccessKit integration. The tracking issue is iced#552 (open since 2020); the live draft PR #3111 demonstrates VoiceOver on one limited Button/Text example; the most complete community attempt, PR #3281, was closed unmerged in Mar 2026. System76’s fork ships a11y today via pop-os/iced. Upstream integration would close the baseline gap in this sample, but still requires widget semantics, adapter QA, maintenance, and upstream acceptance; Floem and GPUI product readiness remain separate gaps.
  2. De-GTK Linux shell integration. Today muda menubars need a GTK window and cannot attach to a plain winit window, tray-icon needs a parallel GTK event loop, and global-hotkey is X11-only; winit has no menu/tray API (winit#403, #3108). Integrating existing Rust portal/SNI/DBusMenu implementations into maintained winit-compatible facades would improve menus/tray/hotkeys for every winit-based framework — and would remove part of the remaining rationale for the tao fork (tao#509, wry#1014).
  3. Explore fontique interoperability for cosmic-text. fontdb has had no release since Oct 2024 and this audit found no announced maintainer succession; cosmic-text uses it and is a significant consumer in this sample. Slint already made this exact migration (slint#9564, 1.14) to fontique. A migration or adapter could reduce duplicate font discovery/fallback work, subject to maintainer and compatibility review.
  4. Sustainability grants for AccessKit and rcodesign. AccessKit has concentrated recent public authorship, and the 2023–24 Sovereign-Tech-Fund-backed work administered via GNOME was mostly wrapped up (GNOME STF report). This audit identified no later direct institutional AccessKit grant; visible support includes personal GitHub Sponsors. rcodesign — the principal open-source Rust-native cross-platform implementation found — has concentrated maintenance and no release since Nov 2024.
  5. Bless a framework-neutral packager. Non-Tauri apps lack one equally integrated bundle + sign + runtime-update chain: cargo-packager had current commits as of June 23, 2026, but its latest release was 0.11.8 from November 2025, cargo-bundle is minimal, dist is CLI-shaped. Improve a shared composition around cargo-packager, or standardize on Velopack (official Rust crate) + rcodesign.