| ▲ | nicoburns 2 days ago |
| If you're interested in a GPU-rendered Rust UI framework, then maybe skip this vibe coded project, and check out some of following established projects: Rust-native GUI frameworks (by crates.io downloads):
1. egui (30.3M total / 9.2M last 90 days)
https://crates.io/crates/egui
2. Iced (3.2M / 770k)
https://crates.io/crates/iced
3. Slint (2.4M / 955k)
https://crates.io/crates/slint
4. GPUI (447k / 255k)
https://crates.io/crates/gpui
5. Dioxus Native (181k / 26k)
https://crates.io/crates/dioxus-native
6. Freya (49k / 12k)
https://crates.io/crates/freya
7. Floem (45k / 15k)
https://crates.io/crates/floem
8. Vizia (7k / 700)
https://crates.io/crates/vizia
List is hand-picked list, ordered by crates.io downloads. I had an LLM fetch the download counts and links. Webview based UI like Tauri and Dioxus Desktop are excluded. As are bindings to native toolkits and GTK. |
|
| ▲ | bryanlarsen 2 days ago | parent | next [-] |
| IMO, the top GUI framework crates for Rust are windows or native-windows-gui, objc2 or icrate for MacOS and gtk4-rs for Linux only. Actually for MacOS / iOS I'd use uniffi to embed the rust core in a SwiftUI app. In 2026 IMO it's much better to use an LLM to keep 3 separate native front ends in sync than it is to try and use any sort of cross platform UI. |
| |
| ▲ | the__alchemist 2 days ago | parent | next [-] | | Could you please explain why? For example: Is it colors? A je-ne-sais-quoi? Widget rounding size and fonts? Performance reasons? Keyboard shortcuts? Do you really find it's easier to maintain 3 separate frontends using an LLM than using EGUI, GPUI, QT etc? I have seen this suggestion several times recently regarding GUI framework threads on HN in the past week (There has been a surge!), but they are always described in the way you did: With no explanation of why. Just an assertion that native UI kits (of which you need a separate one for each OS family) are superior; cross-platform kids are an "inferior experience" etc. I have asked at 3 times and received no answer. I say this as someone who uses both Windows and Linux regularly, and find they are functionally equivalent once you have an application launched. There are ABI differences, driver differences, file system differences, etc which need to be smoothed over with feature gates for certain application functionality, if you're using certain functionality. I want my applications to have the required functionality, run fast, and have a good UI. I don't care if the widgets look the same as on my other applications or the ones built in to the OS; this isn't even a thing because there is so little standardization broadly. Maybe on Macs it's standardized and cross-platform kits look out of place? The proposed approach of "Use LLMs to vibe-code a system of 3 native kits" has cons to weigh. Or making your program Windows only or w/e for a look-and-feel reason or whatever it is has cons too. IMO all our OSes are so similar, PC software should almost all be cross-platform. Exceptions are mostly drivers and driver-adjacent code. | | |
| ▲ | grub5000 a day ago | parent [-] | | Windows and Linux actually feel pretty close these days, and I don’t generally feel any friction switching between them. But when I try to use a Mac it’s another story entirely. That OS just makes no sense to me - the keyboard shortcuts all seem to be insanely bad choices, just inconsistent with huge gaps and divergences from the other OSs. It feels so stuck in the 90s | | |
| ▲ | the__alchemist a day ago | parent [-] | | This checks out. My leading mental model to explain this mismatch is that the critique has been from people who are expecting Mac idioms, which I can't speak to. Window and Linux GUI look/feel are fragmented as-is. |
|
| |
| ▲ | kleeklee 2 days ago | parent | prev | next [-] | | Keeping 3 separate native front ends in sync with custom visual components means you end up building a cross-platform UI. The only apps you can build without custom components are trivial ones. | | |
| ▲ | bryanlarsen 2 days ago | parent [-] | | All 3 have a way of embedding webviews. In my perhaps limited experience, all desire for custom visual components are either specious or for read-only presentation views. In my opinion all controls should be native, but if you ask for a fancy data presentation I have no qualms reaching for a webview. | | |
| ▲ | jasomill 2 days ago | parent | next [-] | | So long as the web views provide for accessibility (and thus UI automation), this sounds perfectly reasonable for the majority of applications. Speaking of which, my dream is an "HTML light" standard with a subset of functionality specifically designed for local UI use, ideally with lightweight non-browser engines supporting this standard shipping with all major OS platforms as shared system components. We had browsers that ran on systems with 8 MB RAM, after all, and while it's not a fair comparison, there's no technical reason why a system with three orders of magnitude more RAM should struggle to run more than a handful of applications merely because they use HTML and JavaScript for rendering. | | |
| ▲ | nicoburns 2 days ago | parent [-] | | I am building such a lightweight browser engine: https://github.com/dioxuslabs/blitz. It targets most of HTML/CSS, but leaves out (or makes optinal) a lot of the extra stuff that browsers pull in). It also has the option to use Rust instead of JavaScript for the scripting layer. Though 8 MB RAM is a non-starter when a single RGBA texture @4k is ~30Mb and modern system often require 2 or 3 for buffering. Somewhere around the 60MB to 100MB mark seems to be the base for modern setups, at least on macOS. |
| |
| ▲ | simonask 2 days ago | parent | prev [-] | | > perhaps limited experience New rule: Programmers with limited UI experience (that includes myself) should abstain from weighing in on what UI designers and programmers need. |
|
| |
| ▲ | tadfisher 2 days ago | parent | prev | next [-] | | An advantage of this approach is that everyone's screen readers and other accessibility tools actually work with your app. | |
| ▲ | treyd 2 days ago | parent | prev | next [-] | | There's also relm4 which builds a Elm-like paradigm on top of gtk4-rs. | |
| ▲ | nextaccountic 2 days ago | parent | prev [-] | | rather than gtk4-rs maybe try relm4 |
|
|
| ▲ | auraham 2 days ago | parent | prev | next [-] |
| https://crates.io/crates/dioxus-native was released 3 months ago and does not have a link to GitHub, I do not think it can be considered as established project yet. |
| |
| ▲ | nicoburns 2 days ago | parent [-] | | (I am the maintainer of dioxus native, and also posted the comment above) So: - The initial version was released over a year ago (3 month is the most recent patch release of the stable version). - It is part of the Dioxus project (https://github.com/dioxuslabs/dioxus) which has been going since 2021 (but the other renderers are web/webview based). - The native renderer (https://github.com/dioxuslabs/blitz) has been under development since December 2024 (building a whole new web engine is just a big project). You're ultimately kind of right that it's not as established as 1-4 in the list. But I think it justifies it's place with the other frameworks lower down the list as one of the lesser-known frameworks that compete technically with those further up the list. | | |
| ▲ | nextaccountic 2 days ago | parent | next [-] | | Is dioxus native usable in android already? | | |
| ▲ | nicoburns 17 hours ago | parent [-] | | To the limit that any Winit-based app is. Which is to say it builds and runs, and there is basic touch and text input support. But system integration is pretty limited. |
| |
| ▲ | kdienxiendkw 2 days ago | parent | prev [-] | | [flagged] | | |
| ▲ | nicoburns 2 days ago | parent [-] | | It's absolutely in good faith. There are two kinds of GUI framework in Rust: - Those people have poured consistent time and effort into over a period of years - Those people vibe code into existence in a couple of weeks and typically abandon after a few months. Nobody wants to waste their time on the latter, so I am pointing people to the former. Yes, mine is one of them, but that doesn't make it bad faith, it just means I know what I'm talking about. | | |
| ▲ | pentaphobe 2 days ago | parent [-] | | You've the patience of a saint to respond so politely to abrasiveness And thanks for sharing the list and saving me from clicking on yet more half baked vibe spam! |
|
|
|
|
|
| ▲ | drnick1 2 days ago | parent | prev | next [-] |
| Stick to Qt, none of those solutions are mature enough for actual production use. |
| |
| ▲ | satvikpendem a day ago | parent | next [-] | | Lots of companies use them in production. | |
| ▲ | embedding-shape a day ago | parent | prev [-] | | Interesting to say given you know zero about the context which other's use it. Not everyone has the same needs everywhere, and blanket saying "No not ready" when you don't understand the context feels very premature, ironically. |
|
|
| ▲ | HackerThemAll 2 days ago | parent | prev | next [-] |
| Yeah, have you tried to do anything in egui? I tried today a ComboBox, but I wanted one with filter input box, "X" icon to clear it, and automatic focus. I've given up when the code reached 300 lines and was still buggy/not working. egui is not mature. I'd prefer declarative approach, data binding, and styling. Therefore will skip egui. |
| |
| ▲ | slopinthebag 2 days ago | parent [-] | | i've built pretty complex stuff in egui. any modern agent will one-shot that component, so i'd say it's more just a lack of familiarity with the library. |
|
|
| ▲ | amelius 2 days ago | parent | prev | next [-] |
| Slint is proprietary. Given that AI makes it so easy to spec out and build even entire GUI frameworks, why would you even go with proprietary anymore? And why doesn't the article showcase a full-fledged set of UI components? |
| |
| ▲ | dmantis a day ago | parent | next [-] | | I might be wrong, but I believe Slint has qt-style dual-licensing and provides AGPL version for GPL projects. I assume you make an open source project giving the critics about proprietary nature, so it shouldn't be a problem. | |
| ▲ | ogoffart a day ago | parent | prev | next [-] | | [dead] | |
| ▲ | xedrac a day ago | parent | prev [-] | | > AI makes it so easy to spec out and build even entire GUI frameworks When a vibe coded gui framework becomes so good that it simply cannot be ignored, I'll believe this can work. Until then, all I've seen is half-baked disposable slop that looks really good on paper. |
|
|
| ▲ | noodletheworld 2 days ago | parent | prev | next [-] |
| > List is hand-picked list, ordered by crates.io downloads. O_o Just say it’s a hand picked list of ones you like and why. Do you like them? Have you used them? I found iced to be unreliable (couldn't reliably render basic widgets); slint overly relies on their DSL and honestly seemed to be moving away from rust; and GPUI felt sloppy. That was my personal “lets try rust gui” journey before I went; nope, guess we’re doing native ui and a shared rust core. This is just a random list of stuff; I can't tell if you think they're all good (I dont) or just copy pasted chatgpt output. For each one: why is it on the list? Do you like it? Why do you think, for example, slint, deserves to be on the list, when you dont even write the ui scripts in rust? |
| |
| ▲ | ogoffart a day ago | parent | next [-] | | (Slint author here) Slint is written in Rust, and Rust API is at its core. That's not changing. What's wrong with the DSL? the UI is described in the DSL, the application logic in Rust. I wrote about why here: https://slint.dev/blog/domain-specific-language-vs-imperativ... What gave you the impression we're moving away from Rust? | | |
| ▲ | noodletheworld a day ago | parent [-] | | The website developer docs. Look, bluntly, you can’t have your cake and eat it to. Either it’s a rust library or it’s not. If you’re not writing your ui in rust, then even if parts of it are implemented in rust, it’s not a rust ui library any more than a js library like calls a c backend is a c library. I really really wanted to like slint and absolutely did not. > Domain Specific Languages like Slint offer a great alternative to traditional GUI toolkit APIs. No they don’t. If you can arbitrarily assert something so can I. A DSL needs it clear the minimum bar of “why is this not just using a real programming language?”. UI programming is tricky, but declarative approaches have almost universally failed, because there’s always some edge case logic that needs a full programming language to handle it. The few UI DSLs that Ive seen work (eg. blueprint) exist a) as stand alone languages, and b) fill a niche that an existing language doesn’t. What does your DSL do that is unique? Why was using js like qt quick not good enough? Why not just use rust? The issue I have with it is you’ve never articulated why it exists. Good DSLs like those implemented using clojure (1) are additions to the language that can natively be mixed into the existing language ecosystem. You could have done the same in rust using proc macros; but instead you’ve chosen (as far as I can tell) to chase the non-rust UI market with a custom DSL. Well.. you want an opinion? There you go. I don’t like slint, sorry. It’s not a rust UI library. It just happens to be implemented in rust, in my opinion. (1) - https://clojure-doc.org/articles/cookbooks/growing_a_dsl_wit... | | |
| ▲ | ogoffart a day ago | parent | next [-] | | > Either it's a rust library or it's not. It is one. Your app is a Rust program that depends on a crate. The UI compiles to Rust code, and we also have the `slint!` proc macro. > there's always some edge case logic that needs a full programming language Right, and that language is Rust. The DSL only describes the GUI. You operate it from Rust. > Why was using js like qt quick not good enough? QML was the inspiration. I worked on Qt and wrote QML bindings for Rust before (qmetaobject-rs). Slint is a new take on it, compiled ahead of time, no GC, strongly typed. | | |
| ▲ | noodletheworld a day ago | parent [-] | | > The UI compiles to Rust Right, so not rust. Languages that compile to c are not c. Languages that compile to rust are not rust. > QML was the inspiration Yes, except you invented a new programming (1) language unnecessarily. Whatever. We'll have to agree to disagree. If the programming language you write is not rust it is not a rust ui library. Slint requires you to write your UI in slint. I havent used it much, but Ive used it enough to know that this: > The DSL only describes the GUI Is about as disingenuous as you can get. Thats like saying that javascript only describes the GUI of a website, a backend rust website is really just a rust application. Really you're building in rust. React is really a rust UI library at heart. <—- obviously BS. (1) - https://docs.slint.dev/latest/docs/slint/guide/language/conc... |
| |
| ▲ | well_ackshually a day ago | parent | prev [-] | | >A DSL needs it clear the minimum bar of “why is this not just using a real programming language?”. No, a DSL only needs to be better than the language itself to write a layout in. UI is a whole different beast than anything else, where deep nesting is common, layouts flow in many ways, and more. Rust is simply not appropriate to make that pleasant. Take a simple layout like you'd declare it in Kotlin using Compose: @Composable
fun GreetingScreen(title: String, onBack: () -> Unit) {
var count by remember { mutableStateOf(0) }
val scope = rememberCoroutineScope()
Column(Modifier.fillMaxSize()) {
Surface(Modifier.weight(1f)) {
Text("Count: $count", style = TextStyles.h1)
}
Button(onClick = onBack) {
Button(onClick = { count++ }) { Text("+1") }
Button(onClick = {
scope.launch {
delay(1000)
count++
}
}) { Text("+1 later") }
}
}
}
Kotlin naturally has trailing lambdas, method references, has the advantage of being a GC'd language so memory management is out the window.In pure rust ? pub fn counter_screen(ui: &mut Composer, on_back: Rc<dyn Fn()>) {
let count = remember(ui, || 0_i32);
column(ui, Modifier::new().fill_max_size(), {
let count = count.clone();
let on_back = Rc::clone(&on_back);
move |ui, col| {
surface(ui, Modifier::new().weight(col, 1.0), {
let count = count.clone();
move |ui| {
let label = format!("Count: {}", *count.lock().unwrap());
text(ui, TextProps {
value: &label,
style: Some(&TextStyles::H1),
..Default::default()
});
}
});
row(ui, Modifier::new(), {
let count = count.clone();
move |ui, _row| {
button(ui, ButtonProps {
on_click: {
let count = count.clone();
move || count.update(|n| *n += 1)
},
enabled: true,
modifier: Modifier::new(),
}, |ui| text(ui, TextProps { value: "+1", ..Default::default() }));
button(ui, ButtonProps {
on_click: {
let count = count.clone();
move || {
let count = count.clone();
spawn(async move {
sleep(Duration::from_secs(1)).await;
count.update(|n| *n += 1);
});
}
},
enabled: true,
modifier: Modifier::new(),
}, |ui| text(ui, TextProps { value: "+1 later", ..Default::default() }));
}
});
button(ui, ButtonProps {
on_click: { let on_back = Rc::clone(&on_back); move || on_back() },
enabled: true,
modifier: Modifier::new(),
}, |ui| text(ui, TextProps { value: "Go back", ..Default::default() }));
}
});
}What a delicious piece of trash. Since you've said no macros, you're carrying an additional variable everywhere (Composer is a Compose system, but you have the same thing in every UI library that does the same. Call it Context, whatever you want). You have shitty lambdas that need to pass the scope too (because Modifier.weight() only works on a ColumnScope). You have no named parameters, and the only way you would would be crap like having a ButtonProps struct. You have impl Fn() + 'static written in your code. And then if you start to want to do some actual work like "clicking on the button increases a counter", you're suddenly spamming Arc::clone, |move| Rc's everywhere in your code because Rust is simply not a good language for UIs. (And if you want to go the old school way of simply managing yourself a widget tree, good luck, not only is it always full of bugs, it's also an unmaintainable garbage fire.) Clojure is not a good language for DSLs either, and the post you've linked is just jerking itself off saying "look i can convert some clojure into the exact bash equivalent by only changing one thing" when it's the exact reason why every single clojure project ends up reimplementing the wheel twelves times and is a piece of shit unmaintainable kludge of whatever code the local genius wanted to commit in this morning. Good languages have constraints. So yes: DSLs _always_ offer a better alternative. QML is a good DSL, and using Javascript is not the reason why. |
|
| |
| ▲ | eaf7e281 2 days ago | parent | prev [-] | | It seems like self promotion, but in a smart way. https://news.ycombinator.com/item?id=50394569#50398826 |
|
|
| ▲ | plaguuuuuu a day ago | parent | prev | next [-] |
| most downloaded is a poor metric |
|
| ▲ | jbirnick 2 days ago | parent | prev | next [-] |
| Luckily GPUI isn't vibe coded at all but a mature and well thought-out project.. /s |
| |
| ▲ | hmry 2 days ago | parent [-] | | I tried using it and yeah, GPUI felt very sloppy. Something about that lack of documentation + having to install it from some subdirectory in a giant monorepo + Tailwind-based API... And the recommended component library for it (GPUI Kit) seems to have been 100% Clauded, down to the website and README. | | |
| ▲ | nextaccountic 2 days ago | parent [-] | | the component library is gpui-component which I think is a too old of a project to have been built primarily by AI gpui-kit is meant to solve your second point: installing it from crates.io rather some unrelated monorepo it doesn't matter if gpui-kit is vibe coded because it's just upstream gpui, repackaged | | |
|
|
|
| ▲ | Varelion 2 days ago | parent | prev [-] |
| Brutal and based |