Rune or GPUI?
c1302026-11-11 · a support page for the framework questionKamal and a colleague asked whether Rune, a new Rust UI framework getting strong reviews, should replace GPUI under the native app. This page sets out the question, the evidence from what qnative has already built, the reasoning step by step, and what would change the answer.
Stay on GPUI Kit for V1. Watch Rune for its agent tooling and its motion, not its looks, and look again in 6 to 8 weeks.
- 1GPUI isn't restricting the look. 28 of the 30 components qnative drew on it match the web at a glance. The two that don't are small text details.
- 2Rune is too young to carry the app. It is 20 days old, has no releases, takes about 100 commits a day, and one person wrote 82 % of it.
- 3What Rune does better is what we built by hand: headless capture, stories, a web-against-native diff, and springs. Those ideas can be borrowed now, without switching.
The question
Rune (github.com/anomalyco/rune) is a Rust UI framework from Anomaly, the company behind OpenCode. It draws its own pixels on the GPU, as GPUI does. It appeared on 2026-10-22 and passed 6,500 stars in three weeks.
The comments that raised it held two claims and a test. We added a third question, because a switch is a trade and both sides of it have to be weighed.
GPUI is better known and has a solid library of components.
True of GPUI Kit in general. Tested here: how much of that library qnative actually uses.
Rune is only interesting if GPUI is proving visually restrictive.
Tested here: qnative c2's fidelity scorecard, 36 rows drawn against the web layer.
What else would Rune give us, and what would it cost?
Tested here: Rune's own docs and repo, against the hand-built tooling in c132 and c138.
The reasoning
Six steps. Each asks one question, answers it from evidence, and says what follows. Green holds GPUI's case, orange is a cost or a risk, purple is what Rune would give.
not restricted: 28 of 30 at fidelity 3
barely used: 2 as is, 0 composed
workarounds, not walls
tooling, motion, some text and layout
age, churn, one author, no PRs
stay, borrow the ideas, revisit
- 1
Is GPUI restricting what we can draw?
Evidence- 30 of 36 web components drawn with GPUI primitives; 28 at fidelity 3 (c2 review-3).
- The two at fidelity 2 are text: word-breaking wrap and outlined text spans.
What followsNo. The colleague's condition for looking at Rune isn't met. On the look alone, there is no case to switch.
- 2
Is the kit's component library what keeps us on GPUI?
Evidence- 2 kit components used as is (Lucide icons, segmented tabs), 0 composed from the kit.
- The kit carries the shell: title bar, sidebar, scrolling, dialog and notification layers, theme.
- Our vocabulary is drawn: about 5,400 lines of components.
What followsOnly in part. The library matters less to us than it sounds, because we draw our own. What a switch would really cost is re-expressing our drawn layer, our stories crate and our tooling, not losing the kit.
- 3
Where does GPUI cost us?
Evidence- Grid layout became flex tracks with zero-height probes that learn a width one frame late.
position: stickybecame a pinned copy drawn in an overlay; SVG became canvas paths.- Headless capture, stories and the web-against-native wipe were built by hand (c132, c138).
What followsIn workarounds and tooling, not in walls. Every page got there, but some took extra code, and the design loop needed its own capture machinery.
- 4
What would Rune give us?
Evidence- Built in:
--snap,--tree,--script,--videoon a fixed clock; a playground with headless tests;kit-diff.py. - Springs that keep their velocity, per-edge layout motion, enter and exit transitions.
- Sticky, vector paths and
wrap_anywhere()built in.
What followsMost of what we built by hand, and some of the friction gone. Rune is designed to be written and checked by agents, which is how we work. That is the real reason to watch it, more than its looks.
- Built in:
- 5
What would Rune risk?
Evidence- Created 2026-10-22; no tags, not on crates.io; apps pin a git commit.
- 2,073 commits in 20 days; 1,705 by one author; outside pull requests not accepted.
- Built to rebuild OpenCode Desktop; no charts or docking in its kit.
What followsToo much for V1. Each update would be a migration, we couldn't land our own fixes, and its roadmap follows another product. These risks fall with time; the gains don't go away.
- 6
So what do we do?
Evidence- The gains are mostly ideas we can copy.
- The risks are mostly about age, which time will tell.
What followsStay on GPUI Kit, borrow Rune's ideas now, and look again when it has releases. Then a one-day spike settles it with our own components and our own budget numbers.
The evidence: what qnative already drew on GPUI
qnative c2 (2026-11-10) ported the pages the native app needs from qdash and scored each web layer component against its native version. Fidelity 3 means indistinguishable from the web at a glance. Source: review-3.md in qnative c2.
- 28 drawn on GPUI, fidelity 3
- 2 drawn on GPUI, fidelity 2DataRankedBars (wraps only at word breaks); Skill Markdown (text runs carry no outline)
- 2 from the kit, as isUxIcon (Lucide), UxTabGroup (segmented)
- 0 composed from the kit
- 3 not built yetno page needed them
- 1 translated awayPeopleOwnerCard: on one machine the owner is you
Where GPUI made us work around it, and what Rune has
GPUI didn't stop any page from reaching the web's look. It made some of them cost workarounds. These rows come from c2's review and c132's loop. The Rune column is from its docs; none of it has been tried in our code.
| The web has | What qnative did on GPUI | In Rune |
|---|---|---|
CSS grid (subgrid, fit-content, auto-fill minmax) | Flex tracks with fixed row heights. Where a width had to be known, a zero-height probe learns it, one frame late. | not documentedTaffy grid is in its plan, but its docs show no grid API. |
position: sticky | The page reads its own scroll offset and draws a pinned copy in an overlay. | built in.sticky_top(), .sticky_bottom(), .stuck_shadow(). |
SVG (polylines, arcs, currentColor logos) | Canvas paths, and recoloured images cached per logo and colour. | partlyVector shapes with Bézier paths (El::shape). Recolouring logos not checked. |
break-words | An ellipsis. DataRankedBars sits at fidelity 2 for this. | built inwrap_anywhere(), CSS overflow-wrap: anywhere. |
| Outlines on inline text | Tints. Skill Markdown sits at fidelity 2 for this. | partlyA background per text range, and inline pills. No outline per range found. |
| Eased height (StretchBox) | An animated max height with the same easing. | built inLayout springs per edge that keep their velocity when retargeted. |
| Capture, stories, the web-against-native wipe | Built by hand: c132's native capture mode, the stories crate on GPUI's test support, scripts/tokens-to-kit.mjs. | built inEvery app takes --snap, --tree, --script, --video; a playground with headless tests; kit-diff.py scores Storybook against native. |
Side by side
The facts, read 2026-11-11 for Rune and 2026-11-09 to 11 for GPUI Kit. Each side's numbers are its own, so compare within a row with care.
| Rune | GPUI Kit (what qnative uses) | |
|---|---|---|
| Who | Anomaly (OpenCode). The same org as strobe, which we use for the budget. | Longbridge (Jason Lee), on GPUI from Zed. |
| Age | Created 2026-10-22: 20 days. | Began 2024-06-13 as gpui-component; GPUI Kit since 2026-09-03. |
| Releases | None. Not on crates.io. Apps pin a git commit of dev. | 0.9.1 on crates.io, weekly, in step with gpui-pre. We pin =0.9.1. |
| Licence | MIT. | Apache-2.0. |
| People | 6,598 stars, 11 contributors; one wrote 1,705 of 2,073 commits. No outside pull requests. | 20,096 stars, 233 contributors, plus Zed upstream. |
| Issues | 300 open, 14 closed (GitHub search). | Not read for this page. |
| Components | About 30 controls, plus Tree, Table, Markdown, Diff and Mermaid. No charts, no docking. Named after @opencode/ui. | 80 component pages and 40 primitives, including DataTable, charts, Dock and an editor. |
| Engine | Its own renderer on wgpu, winit, Taffy, Parley and AccessKit. | GPUI: Metal, Direct3D 11, wgpu on Linux; Taffy layout. |
| Platforms | macOS, Windows, Linux; experimental WebGPU. | macOS, Windows, Linux stable; wasm showcase only. |
| Accessibility | AccessKit on by default. | AccessKit in GPUI; qnative's table has roles and two tests. |
| Agent tooling | Headless snap, tree, script and video in every app; playground; web diff. | llms.txt, two skills, headless test support; the rest built by us. |
| Motion | Springs with velocity, per-edge layout motion, transitions, reduced motion. | Animation by rebuilding the subtree each tick; a spinner cost 85 % of a core upstream. |
| Memory | Its settings window settled at 70 MB after a fix (their figure; target 50 MiB RSS). | qnative window 62 MB private, tray 21 MB (c2). Different metrics. |
| Binary | 9.3 MB stripped (the settings example). | 23.2 MB (the whole qnative app). Not like for like. |
| In production | Rebuilding OpenCode Desktop is its flagship test, under way. | Longbridge Pro on three platforms; 15 more apps listed; Zed itself. |
Rune's pros and cons, for qnative
Each point says why it matters to us, not in general.
Pros
Agent tooling is built in:
--snap,--tree,--script,--videoon a fixed virtual clock.c132's native capture mode and the stories crate build this on GPUI by hand.
A storybook with headless unit tests ships with it.
Our stories crate (c132 D1) maps onto it almost row for row; its docs show the mapping.
kit-diff.pyscores each Storybook story in Chromium against its native render.That is the c132 D7 wipe, automated. rune-kit is itself a web design system ported to native, as ours is.
Motion is first-class: springs keep their velocity, layout moves per edge, reduced motion is built in.
GPUI rebuilds the subtree on every tick of an animation.
More visual primitives: radial gradients, inset shadows, backdrop and subtree blur, system materials.
Headroom for effects GPUI lacks.
Sticky, vector paths and
wrap_anywhere()are built in.Three of our workarounds, and one fidelity-2 gap, would go.
Small and quiet: 0.13 ms mean frame CPU, one draw call, nothing drawn at rest.
The same discipline our budget holds the app to.
Docs written for agents:
AGENTS.md,CLAUDE.md, a 2,900-line crate README.Partly makes up for being absent from training data.
Cons
20 days old, pre-release, not on crates.io.
GPUI Kit ships versioned releases weekly.
About 100 commits a day; a 3,200-line changelog in three weeks.
Every update would be a migration.
One author wrote 82 % of the commits.
GPUI Kit has 233 contributors, with Zed beneath it.
No outside pull requests; issues only.
We couldn't land our own fixes. We'd carry patches or wait.
Built for one product: the kit mirrors
@opencode/ui.Our needs (tables, charts, a tray-first app) would ride on someone else's roadmap.
No charts or docking in its kit.
GPUI Kit has both, though we draw our own charts today.
Open desktop gaps: no run-time URL-scheme claim (#636), no credential store (#635); text input is its own top risk.
Tray windows, notifications and deep links exist: about even with GPUI Kit.
The switch would cost our drawn layer, the stories crate, devmode and the capture loop.
All re-expressed in a different state model: a plain view function, not GPUI entities.
How much to trust this
What would change the answer, and what to do now
Borrow the ideas
- Shape qnative's dev-mode and stories command line after
--snap,--treeand--script(c132, c138). - Score the web-against-native wipe per story, as
kit-diff.pydoes.
Look again, with a spike
- Once Rune has tagged releases and its churn slows.
- One day: DataRankedBars and the Status page in Rune, a headless snap wiped against the lab capture, a strobe reading with the metric stated.
Something changes
- Motion becomes a design priority: springs, choreographed transitions.
- A third visual gap appears that GPUI can't draw.
- The cost of our hand-built tooling keeps climbing.
Sources
- anomalyco/rune · the repo, dev branch
- PLAN.md · direction, targets, risks
- crates/rune/README.md · the framework, agent tooling, playground
- crates/rune-kit/README.md · components, kit-diff
- research/01-gpui-zed-warp.md · its case against forking GPUI
- Issues #635 and #636 · credential store, URL scheme
- research/rune.md · the written note behind this page
- research/gpui-kit.md · the kit we build on
- research/comparison.md · the five-way comparison (before Rune)
- qnative c2 review-3 · the scorecard and the workarounds
- c132 Native Design Prototyping · the loop and its capture modes
- c138 Developer Mode · the dev tooling in qnative c3