I'm a bit concerned with Egui gaining in popularity for general purpose GUI applications. It's leading to feature bloat, and probably more overhead. The stated goal originally was that Egui should use less than 1% of main thread frame time.
Originally, Egui was completely one pass. The API looks more general than that; you can align things against the bottom or right, and get things above or to the left to adjust. But originally, that didn't work. You pretty much had to lay out widgets down and to the right. This is fast and simple. Lots of stuff didn't work, such as scrolling text boxes with line wrap.
But users doing ordinary GUI work are demanding more and more layout features, and won't stop until they get browser level layout. Overhead is increasing.[1] This is a problem in Rust game land, which is tiny. At some point, someone may need to fork Egui and create Egui-lite.
While I agree that the maintainers of any project have to know when to say no.
If your UI lib is not doing scrolling text boxes with line wrap, can't have different alignments, doesn't have a solution for context menus, then what good is it?
I remember that I essentially had to code it myself a few years ago, but I can't remember if it was egui or imgui.
piker 2 hours ago [-]
Hmm. It seems to me that one of the features of an immediate mode library is that if you don't call something, you won't suffer overhead consequences. If you aren't trying to align things in a manner that triggers the two-pass rendering, then you shouldn't be affected by the associated performance hit.
I guess you worry that the feature creep dilutes the maintainers' focus, but opening it up to a broader audience might get access to more contributors.
Animats 2 hours ago [-]
> I guess you worry that the feature creep dilutes the maintainers' focus, but opening it up to a broader audience might get access to more contributors.
To some extent, yes. Here's an example.[1] So many features have been added that the unit tests were taking too long. So tests were switched to use a faster allocator. That won't even compile for cross-compilation from Linux to Windows.
Because tests won't run, chasing down other cross-compilation bugs got much harder.[2]
This is the price of feature bloat. Core stuff is breaking and not getting fixed as cool features are bolted on. Currently, 799 open bugs. The technical debt is building up.
It reminds me a little bit of the inescapable lifecycle of a ticketing system:
1. People love it because it's lightweight and fast.
2. More and more people use it.
3. Feature requests start to roll in.
4. It becomes bloated and slow.
5. People get fed up and start to hate it.
6. Create a new ticketing system and return to step 1.
diggan 40 minutes ago [-]
Maybe we should just learn to live with that sort of things, and build a tool/product that works with that cycle in mind and offers it as a feature.
ezekiel68 13 minutes ago [-]
This doesn't strike me as the kind of challenge a tool/product can address.
Animats 2 hours ago [-]
Two-pass rendering was considered and rejected by the Egui developer. What they have is sort of one and a half pass rendering. Sometimes, things are wrong on the first draw, but correct on the next draw because info is retained from the previous frame.
Back in 2023, this created a bug where a text box was misaligned on alternate frames.[1] Amusingly, I tried to capture a video of this, and the 30 FPS video looked perfect, because it was capturing only alternate frames of 60 FPS refresh.
Originally HTML was one-pass. Until they added tables. And tables require at least two passes to lay out.
There's only so far that you can take one pass rendering
Animats 5 minutes ago [-]
> There's only so far that you can take one pass rendering
Right. The whole point of Egui was supposed to be that it was a game renderer, a text and button overlay on the game graphics. Not the entire screen. That's why it's immediate mode. It's supposed to redraw on every game frame. Most UI programs don't need or want that.
But it was better at the basics than anything else in Rust, so it caught on for routine non-game programs. And here we are.
merksoftworks 11 hours ago [-]
So egui is great for projects where the application runtime is short lived, or for overlays in longer lived projects. The visual equivalent of scripts, where you know you need a small amount of immediate visual feedback and tweaking parameters for it to be useful to the end user.
Flutter answers questions about more robust UI.
It's good that you chose the right tool for the job and more people should know that there are options. But fundamentally I'm most motivated by the possibility of a robust UI framework made from first principles to be as low friction as egui but with the accessibility, performance, and visual flexibility of stylable retained mode guis.
Raph Levien and the xilem project might be getting us closer.
piker 10 hours ago [-]
Both approaches have their downsides and, in my view, retained mode and immediate mode tend to converge as the UI complexity increases. So far, no problems with implementing any UI I want in my experience with egui on a somewhat complicated application (Desktop word processor). Immediate mode is a breath of fresh air from React.
[Edit: although the standard accessibility criticisms apply to my application; although that's more of an issue with my implementation than an indictment of immediate mode generally.]
ethin 3 hours ago [-]
Accessibility problems are something both retained-mode and immediate-mode UIs have generally. I've found that you can kind-of hack it together but the best route is to incorporate the actual accessibility frameworks of the operating system(s) your targeting. Egui was doing this at one point I think but I'm pretty sure it's either broken now or just doesn't work all that well.
miki123211 2 hours ago [-]
The problem with immediate mode is that most a11y frameworks expect all UI elements to have a stable identity.
Imagine you have a to-do list of 100 items. What happens when a remote user drags and drops item 100 to lie between items 1 and 2? In retained mode, that's clearly communicated to the UI toolkit; the widget representing that todo is told to change its position in the list. In immediate mode, you can't just destroy and re-create the a11y tree on each render. You need some kind of tree diffing algorithm to figure out that it's one op (move item) instead of ~200 ops (change the name and checkbox state for all items between 2 and 100).
spookie 2 hours ago [-]
There are libs that function as a messenger between your "hack" and the OS on this.
You don't lose anything.
This is but my opinion, but toolkits tend to be opinionated piles of **. Talking directly with the GPU to paint stuff is often just saner to me.
mhast 5 hours ago [-]
From what I've seen immediate mode seems suitable for less fancy UI requirements. If you want to start having a framework solve things like animations and such then you'll probably end up with some form of retained mode.
Over my years making UIs I've found most of the bugs you get is due to incorrect state handling in applications. Having a framework you use which is opinionated and helps you solve that is pretty nice. (If your UI requirements are such that you need it.)
the__alchemist 8 hours ago [-]
I'm curious too. I currently have both a plasmid editor, and protein/molecule viewer using EGUI. Both have complex UIs, and I haven't hit roadblocks. I think the protein viewer might be more of a canonical immediate-mode case, because most of the window is a 3D render, but it still has a GUI above it.
smj-edison 2 hours ago [-]
Kind of off topic, but a protein viewer in Rust sounds really interesting! Is the source code available? I'd love to poke through it (understandable if not though).
> egui is great for projects where the application runtime is short lived
What is good for a long-lived application, such as an email client? I'm looking for something that fits the same place that Qt fits in the Python world.
Accessibility and keyboard shortcuts are of extreme importance.
Aeolun 11 hours ago [-]
If your UI is fast enough, why not in complex UI’s either? I’d say it gives you good motivation to keep your UI handling code as fast as possible.
mort96 10 hours ago [-]
Doesn't egui always re-render? I like my idle apps to be doing nothing, I don't want them running their render loop in the background
throwawayffffas 11 minutes ago [-]
You typically set it up so that it does not re-render when it's idle. Or at least not at 60fps.
By the way once upon a time, visual studio code I think it was, was using like 20% cpu when idle just because of the blinking cursor, fun.
the__alchemist 8 hours ago [-]
I think the default behavior is to only re-render if the window is active/focused. You can trigger a render at specific points, including in the main loop, which will result in the behavior you mention.
This can be problematic, e.g. some of the sensor interfaces I have, I want to always display correct data, even if not focused. So, I have to decide if I want to have old data shown in the background misleading users, or have a per penalty from constant renders. Or try something else to be clever. (Maybe have it update at a low rate if not focused? I think that's the move...)
andsoitis 5 hours ago [-]
> You can trigger a render at specific points, including in the main loop, which will result in the behavior you mention.
sounds analogous to manual memory management
hoppp 1 hours ago [-]
Which is completely fine.
There are bugs but unlike with memory management, render bugs are more in your face.
user____name 10 hours ago [-]
Any quarter decent imgui implementation will idle when there's no input or active animations, and the renderer can generate dirty tiles or rects to unnecessary redrawing -- if it matters, gpus are ridiculously overpowered for drawing a bunch of rectangles. Ui logic is usually firmly in the microseconds realm.
mort96 10 hours ago [-]
I agree that this is not a necessary downside to immediate mode GUIs, but we're talking about egui specifically here. AFAIK, egui always redraws at some relatively high rate even when nothing is happening. (I'm having trouble finding documentation about what that rate is though.)
Boxxed 6 hours ago [-]
That's not true, it only re-renders if there's an input event or an animation running. This is very easy to see if you just put a `println!` in your UI logic.
> egui only repaints when there is interaction (e.g. mouse movement) or an animation, so if your app is idle, no CPU is wasted.
amelius 3 hours ago [-]
Iiuc, a tiny clock in the top right corner of the screen will trigger O(n) work where n is the number of elements on the entire screen. On every change of the clock, e.g. every second. This may be more if there are smooth animations, e.g. 25 times per second if that is the animation frame rate.
ModernMech 6 hours ago [-]
There are two modes, reactive and continuous. You can switch between them here in the backend tab:
I really wish this were built into imgui as a first-class use case instead of requiring a hodgepodge mix of unofficial hacks.
I recall the author posting an imgui update saying this will be an officially supported mode, but AFAIK it's still not the case. Otherwise I would be building all my applications with imgui going forward.
Re-rendering the screen, even if it's fast, incurs a lot of memory bandwidth to draw everything and swap framebuffers etc. Not something you'd like to happen on mobile, in particular. Just because the waste is "small", doesn't mean it's acceptable.
halfcat 2 hours ago [-]
Does ImGui work on mobile? I’ve seen it run in web assembly on mobile but typically none of the keyboard inputs work (the mobile keyboard doesn’t pop up, so effectively it’s not usable, at least in that approach).
WhyNotHugo 2 hours ago [-]
I suspect (and hope) you can block the main loop if no events are received. This avoids re-rendering if the UI is not visible and no interaction has happened.
freefrog1234 10 hours ago [-]
By default it re-renders on each event. This isn't often on mobile apps, but moving a mouse across a desktop app triggers multiple vents. There is a function call to request a re-render if you want not to wait for an event.
mort96 10 hours ago [-]
So if it's just an idle visible application, does it not render at all because there are no events? Or am I right that there's some idle redrawing going on
Philpax 9 hours ago [-]
With eframe, it does not re-render when idle, no. You need to have another thread that forces it to redraw on your own schedule. It will also redraw when an event occurs (mouse movement, keyboard presses, interacting with the application in general.)
baq 10 hours ago [-]
do you run without a compositor? I get where you're coming from, but 'idle' can mean a lot of different things and redrawing the whole UI at 60hz is not necessarily 'not idle' nowadays.
mort96 10 hours ago [-]
I run with a compositor, which is exactly why it's so great for the application to just draw its window once and then the compositor has the window's contents as a texture. The compositor can do whatever it wants with that texture without involvement from the application.
j45 3 hours ago [-]
Appreciate the thoughts about both Flutter and egui.
It's not perfect, but I don't know if there's much on the market that addresses robust UI and single code base as well as Flutter.
Very open to other things that are not more complex than Flutter to accomplish the single codebase to multi platform solution it does provide.
strogonoff 12 hours ago [-]
Immediate mode GUIs are cool but it seems that accessibility support is somewhat lacking. In native frameworks you often get it for free, on the Web you can follow ARIA and get it for free, but with immediate mode GUIs it seems that it is always a bit of an afterthought. For example, it seems that egui supports AccessKit, but not when used on the Web. With Dear ImGui it seems worse, there is some effort in that direction but tickets about accessibility are open (this is based on a quick scan, I may be wrong).
I guess it makes sense since immediate mode focuses on speed and applications like games, but if only there was best of both worlds.
Philpax 9 hours ago [-]
The lack of accessibility on the web is less an immediate mode problem and more of a problem with eschewing the web's native UI stack and rendering everything yourself. There are ways to signal to the browser what the content of your custom rendering is, but they very much do not come for free and require much more integration than AccessKit does on native.
troupo 39 minutes ago [-]
> more of a problem with eschewing the web's native UI stack and rendering everything yourself.
Because web's "native UI stack" is almost non-existent for actual UIs. This has started to turn for the better only very recently: https://open-ui.org/
zigzag312 10 hours ago [-]
Is there any technical limitation that accessibility support is usually lacking in immediate mode GUIs? Or it's just a lot of work?
Flutter, which does its own rendering of controls, needs to implement a lot of accessibility features by itself.
baq 10 hours ago [-]
'a lot of work' is probably an understatement. one of the reasons everybody embeds browsers nowadays is all the text rendering quirks (e.g. right-to-left) are solved - and some of it includes accessibility (like easy theming, scaling, aria, screen reader support, etc.) browsers spent a lot of resources to make this happen.
bunderbunder 4 hours ago [-]
Just shooting from the hip, it's a lot of work, but even more importantly it's running slightly counter to the core motive behind many immediate mode GUI toolkits, which is to be as minimalist and easy to work with as possible.
For my part I have some accessibility needs that typically aren't well supported by immediate mode GUIs. And my personal take is, this is 100% fine. If you're working on a thing where an immediate mode GUI toolkit is even a realistic option, you're probably also in a situation where it's exceedingly unlikely that making your hobby project or prototype or whatever harder to work on will cause a net increase in humanity's overall sense of wellbeing.
And if something comes up and you do end up needing to make changes for someone else's benefit, hey, good news, immediate mode GUIs are really, really easy to hack on.
4 hours ago [-]
newswangerd 8 hours ago [-]
I've been doing something similar to this, except with go. In my case I have a flutter frontend and a go backend that's built using go mobile. Instead of trying to figure out how to make all of my go functions use data types that are supported by the various native frameworks, I've opted to use protobuf objects for every type that is shared between the frontend and backend. This way I can expose a single go function via the flutter FFI that takes in a binary array and then converts it to a protobuf object. This gives me a nice separation of concerns between my business logic and frontend while also providing easy to use objects for the front and backend.
Not sure that I'd recommend this approach to everyone. Protobuf code generation can be finicky to set up, but I'm doing it so that I can access go's rich array of libraries in my app.
My music model is all Protobuf messages, which go from Dart/Flutter land to Kotlin/C/Swift/JS audio backends on target platforms. I also use Protobuf for saving and sharing. It’s been incredibly resilient and performant.
written-beyond 5 hours ago [-]
I don't understand what you mean by frontend and backend when you mention ffi. Is this backend in a remote server or just on the same app?
I used proto buf with rust, I had a rust client that spoke to my flutter frontend via dbus. The rust client connected to my remote server via a web socket and all messages were wrapped in protobuf and sent as binary. Made everything a lot more concrete... But it basically forced me to build my own much shittier version of gRPC. Since, if the wan for your network was every killed the client was notified too late and you'd end up with missing messages if the network buffer got filled. We added a message id and acknowledgement process with sqlite backing up each message.
I still have nightmares about why I built that.
nu11ptr 7 hours ago [-]
Have you considered just using gRPC in this case? You gain 100% language separation (no FFI) and remote client/server at the cost of a little more call overhead.
foobiekr 3 hours ago [-]
Most of the gRPC implementations force buffering of the whole response for large unary responses. They are not really written by people who care about performance. It’s dumb because the protobuf binary marshaled format is perfectly designed for server-side incremental marshaling.
nu11ptr 3 hours ago [-]
Performance is relative. gRPC is plenty fast enough for my use case, and for that matter, almost all client/server use cases that work across the Internet. If a Javascript web client against a REST backend is fast enough latency-wise, then a local gRPC connection on a single PC is gonna feel like greased lightning. Of course, there will be a few scenarios where tight coupling of client/server are required for good enough performance, but they are few and far between.
klabb3 7 hours ago [-]
Not OP but in same situation. Not every platform can run gRPC over localhost easily or without extra privileges.
I used to use protobuf but now I just use JSON, over stdin/stdout on desktop. It’s honestly quite good.
nu11ptr 6 hours ago [-]
Which platforms? My product runs gRPC client/server on macOS, Linux and Windows. No issues with privileges. Or are you trying to run it on port 443? Yeah, don't do that, run it on 8443 or whatever instead.
dvdkon 3 hours ago [-]
Then you have to deal with port collisions when some other software wants to use that port. And keeping a port open without any authentication is terrible for security, even if it only binds on localhost, so you have to find some secure way to share a key between the client and server.
Personally I wish we could just use UNIX sockets for "localhost-only TCP", but software support is just not there.
nu11ptr 3 hours ago [-]
I don't worry about security too much given it is just bound to localhost, but I do use a simple password (and make it modifiable by the user). Avoiding port collisions in the real world isn't a big issue, just ask an AI for the least assigned default ports and chance of collision is minor (in worst case, also user modifiable). In return, you get free "remotability", which is kind of a big deal IMO.
I do wish gRPC allowed for easy usage of UNIX domain sockets and perhaps named pipes, however. Sometimes all you need is IPC, but in my case, I'm happy to have remote usage builtin.
cyberax 7 hours ago [-]
Why not ConnectRPC? It's basically gRPC but without all the strange requirements for exotic HTTP features.
nu11ptr 6 hours ago [-]
I actually use this currently. Not nearly as many platforms, but you an always fallback to gRPC.
the__alchemist 7 hours ago [-]
Hah yea. I just did a deep dive into protobufs and RPC for an embedded application. Left learning a lot, and with a headache. Part of it was because this was using heapless, and I got errors until I configured the generator to use the right Vec sizes.
turtlebro 8 hours ago [-]
That's a perfectly fine approach, Protobuf strength is exactly these kind of use cases.
paldepind2 10 hours ago [-]
> A quick Google search with "flutter setstate is not refreshing" reveals a struggle that you will face quite often when running Flutter. It sounds like an easy fix, but the nature of Flutter using a bunch of nested Widgets creates, naturally, lasagna code that makes it hard to reason about this.
Can you expand on this OP? I've never had problems with `setState` nor "lasagna code" in Flutter. From a quick search I mostly seem to find questions from people who are still learning Flutter and getting basic things wrong.
doawoo 4 hours ago [-]
State management in flutter can be done in so many ways so I get why it could feel complex, we’ve used Hooks a lot and it simplified a ton of stuff. Can also go the whole BLOC route too. Having issues with setState means you’re doing something that’s an anti-pattern
lazypenguin 8 hours ago [-]
There’s a big advantage to having your whole application in one language. I’m not sure the experience of egui on mobile though but egui is great to use as a developer
Pros
- Solid widget set
- Easy to get started
- Less state management
- Easy to make custom widgets
- Active community and crates (e.g docking view, tables, etc.)
- Fast to build new Ui
Cons
- Harder to do layouts (has multipass and some flexbox crates but still hard and compile loop makes it slow to iterate)
- Bring your own architecture (no restrictions on how you build your app so easy to make spaghetti if you’re not careful)
Egui is currently my favorite Rust UI crate although Slint and iced are also interesting.
I still prefer good old GUI frameworks with WYSIWYG designers.
ezekiel68 47 seconds ago [-]
Funny you should say that. I remember using a Microsoft product back in the '90s that featured WYSIWYG forms. As a programmer, though, you couldn't imagine my joy at discovering I could define and configure the UI in code instead! It felt magical and far more powerful.
jeroenhd 11 hours ago [-]
I think Slint is getting pretty close to that these days: https://slint.dev/
No quick and easy drag&drop just yet, but IDE support for live preview rendering makes it come pretty close. I do long for the Visual Studio GUI design days, but things aren't as barebones anymore as they used to be in open source Rust land.
taeric 5 hours ago [-]
I will forever harp on the idea that we really set web design back by putting so much focus on the HTML. Dreamweaver sites were not great, to be sure. But they had more creativity and design than the majority of what we seem to create nowadays.
bigstrat2003 2 hours ago [-]
I miss WYSIWYG designers so much. I used to use them to make small apps all the time because, while I'm a good programmer, I'm awful at trying to lay out a UI in code. WinForms in Visual Studio used to be great for people like me!
jenadine 10 hours ago [-]
WYSIWYG designers seem convenient, but they're not that popular anymore for a reason. Writing UI in code is more flexible, easier to maintain, and works better as projects grow.
jayd16 2 hours ago [-]
Wah? WYSIWYG rules the world. Web, mobile, desktop, game dev (The UI the user sees anyway). Anything where visuals matters, WYSIWYG and predefined layouts are used.
IMGUIs are almost always relegated to debug UIs and single devs because its actually terrible to maintain something that binds presentation and business logic like IMGUIs often do (and when they don't they lose the simplicity).
alkonaut 7 hours ago [-]
WYSIWYG doesn't necessarily mean you are limited to using some designer and can't edit code. It's enough (and better) to have a live preview, than a full designer. It just means you see live what the code does, at the point when you write it, not later when you run it.
When hand-writing XAML or similar, it's great to see the UI created live. Like editing markdown and seeing the preview, versus editing markdown and not seeing the preview.
alerighi 9 hours ago [-]
In the end the WYSIWYG would produce an XML file that you can put under version control. All depends on the UI of the thing your are building, if what you are building only needs to be functional and nobody cares about the UI (that is always the case of internal use software, that needs to have a good UX but who cares if it has the Windows 95 style controls, like machine HMIs, ERP software, etc.) WYSIWYG (like Visual Studio) are good to write things fast and typically with a consistent layout.
I mean, most companies are not building a videogame, and most people are still fine using things like AS/400, so...
jenadine 9 hours ago [-]
But those files are often hard to read and merge.
If WYSIWYG really worked well, why aren't more big projects or popular frameworks using it? Why do you think it's become less popular over time?
mattmanser 8 hours ago [-]
Because editors stopped trying to do WYSIWYG. It's not that the demand isn't there. They stopped trying about the time monitors went from a couple of quite similar fixed widths of 600/768 to more. Then smart phones came along and really killed the WYSWIG editor. I worked with Silverlight for a year in the late 2000s, and even by then WYSWYG editors were struggling. You sorta still had some for flash and stuff. They were trying to bring back a WYSWIG editor for it (and for WPF in general after silverlight flopped). But it was pretty clunky still. There's a lot of hard problems about how you anchor elements, how things scale, that are much easier to express in code than in a properties panel.
You can see the demand in the sheer number of WYSWYG editors for the web.
But for development, basically all the big players stopped trying or died for other reasons. I just think no-one's got the will to try it.
I think it could be a huge opportunity for someone. Right now, with AI coming to the fore in development, seems to be when it would become absolutely killer for less code orientated people making their own apps by adding/dragging controls around and telling an AI what each control should do. All without a programmer involved. The AI could even "solve" the hard problem of a good responsive WYSWYG editor by making assumptions of how the user probably wants the controls anchored.
So I think that's the market we'll see a WYSWIG editor emerge again for.
taeric 5 hours ago [-]
Agreed with your general push here, I think.
I would add that a large part of the push away from it came from not having dedicated design and development teams. Is, I think, why industries such as gaming have stuck to a lot of these workflows. You have art designers creating the assets and hand them off to an integration team that will get them into the game. Tooling is specifically made to integrate the art and the program.
In the web, we seem to have tried to converge all of that tooling into the symbolic text. Works great when it can work. But it greatly limits what you can graphically do. And is largely why we don't design things graphically anymore.
mhast 5 hours ago [-]
On Android (and I'm pretty sure iOS) you have WYSIWYG editors for UI layouts for jetpack compose and flutter (and on iOS it would be Swift UI).
These all go direct to code instead of XML or some other extra layer of code.
What I would probably focus on is better integration with Figma and similar tools. Use that to do the WYSIWYG part and then generate corresponding code (possibly with LLMs).
The biggest limitation you tend to have in WYSWIG is that at some point you really need to have the true data the user sees to ensure everything looks good. That becomes a bigger hassle than coding the UI manually. (Particularly when doing multi-platform things.)
eviks 4 hours ago [-]
Because it's much harder to do better design, so often over technological soft good things fall through the cracks.
Like, why aren't more big projects use accessibility as hot reloading if those are so great?
Or, a simple illustration to your reliability point - part of the reason the files are hard to read is because XML is an atrocious format. And also tools like VS aren't even smart to preserve user formatting, so you can't even manually make it easier to read. Why hasn't it been changed in so many years?
gman83 6 hours ago [-]
I tried FlutterFlow but found I actually preferred writing everything in code. Also LLMs are great for writing Flutter layouts.
rossant 8 hours ago [-]
I really like the immediate mode GUI (IMGUI) paradigm. The other day, I looked into whether any web-based IMGUI libraries existed. It seems that HTML and the DOM are designed so differently from IMGUI that such an approach doesn't really make sense, unfortunately, unless everything is rendered manually in a canvas, WebGL, or WebGPU, which brings its own set of challenges.
ar-nelson 8 hours ago [-]
I really like Mithril.js (https://mithril.js.org/), which is, IMO, as close as it gets to web IMGUI. It looks a lot like React, but rendering happens manually, either on each event or with a manual m.redraw() call.
k__ 7 hours ago [-]
I think, similar to Preact, Mithril skips the VDOM, which makes it "more immediate" than React.
However, updating the DOM and then turning the DOM to an image (i.e., rendering it) still has an indirection that using canvas/webgl/etc. don't have.
nathcd 1 hours ago [-]
> I think, similar to Preact, Mithril skips the VDOM, which makes it "more immediate" than React.
I don't have too much experience in GUIs and I've been looking at iced and gpui recently for a new GUI application.
iced has some nice looking apps written using it, but they all seem "laggy" on my high-end Linux box somehow. I'm wondering if this is a limitation of the immediate mode GUIs, or something related to my system, or an issue in the apps?
For example, drag-and-drops or selecting text with mouse lag behind the mouse cursor.
I'm wondering if I'm not holding it right somehow?
airstrike 1 hours ago [-]
iced is not immediate mode
which apps are laggy? iced is fast AF. try running the game of life example on release and crank to max speed. there is literally no lag
could be something wrong with your GPU. join the Discord and we'll help you debug
ogoffart 9 hours ago [-]
Since others are sharing Rust GUI libraries, I’ll mention Slint [https://slint.rs] a native GUI toolkit written Rust. It has a declarative domain specific languages, editor tools, and has been stable with no breaking API changes since 2023. I'm one of the developers.
mtndew4brkfst 8 hours ago [-]
Anyone considering it will need to decide for themselves how to feel about it, but I think it's important to prospective users to highlight that the current licensing model for Slint requires either GPL3-compatible licensing of your work, advertising for Slint within your own software, or paying ongoing licensing fees and/or royalties.
I only mention this because those constraints are notably more restrictive than the vast majority of the Rust crate ecosystem.
I take no particular stance on whether this is a fair or good practice or about the technical suitability of Slint beyond this concern, I just think it's a hurdle for most people so they should be made aware early and often.
OskarS 6 hours ago [-]
I really like this model of ”GPL3, but commercial licenses available”. Means you can have a sustainable business without sacrificing open source. I wish it was more widespread, the prevalence of extremely permissive licenses has led to so many enormous companies using open source without giving back.
ogoffart 5 hours ago [-]
We're building Slint as a business. It takes a lot of time and effort to maintain and improve it.
We're not looking to support users who want to use it in proprietary software and give absolutely nothing back, not even a small credit. That doesn’t feel like too much to ask. (Even the MIT license requires including a copyright notice.)
Honestly, it’s a bit sad that for some, using libraries for free isn't enough, they also expect to do so without even mentioning the project.
bigstrat2003 2 hours ago [-]
One of the things I appreciate a lot about Slint is that you guys are, as far as I can tell, the only GUI toolkit devs who thought to include a menu widget. Desktop applications need a menu bar! So that means that, for me at least, Slint is the only viable option out there.
the__alchemist 7 hours ago [-]
I love how y'all target embedded. I love EGUI for PC applications, but will try Slint next time I'm doing an embedded device that has a display.
inferiorhuman 2 hours ago [-]
A few months ago I was working on a debugger for some oddball VM. Slint suffered from the same issue most (all?) rust GUI toolkits seem to suffer from: immaturity. Either the widgets I was looking for weren't there or customizing them was a huge endeavor. With Slint specifically it was the inability to style text.
For my use case it was easier to get up and running with a TUI toolkit (ratatui in my case). Plenty of limitations there too alas and I finally landed on Qt…
eviks 5 hours ago [-]
> That didn't happen, so the Flutter capabilities were very underused.
> I didn't even make an effort to make it look good
Makes sense to use a primitive instrument to satisfy primitive needs, those eschewing a lot of extra complexity.
Though if some funding does fall through for better gui, isn't that a risk of having to do another switch?
kjuulh 12 hours ago [-]
I actually wanted to ask you about this at our last meetup (Rust Aarhus), so nice to see it on hackernews. It did seem you switched away from flutter. ;)
How is shipping egui apps vs flutter. I'd imagine that especially shipping a rust integration with Flutter might be a bit of a pain
wdroz 11 hours ago [-]
I also prefer the mental model of immediate mode, but when I played with Dioxus[0] for a rust fullstack hobby project[1], I was able to adapt.
I liked the DX with the tools and the `rsx!` macro. The use of `#[cfg(feature = "server")]` to define server-side code is interesting, it lets you keep a shared codebase for frontend and backend, while still controlling what gets compiled to WASM for the client.
The nice thing about Flutter is that its cross-platform, write once run anywhere, I use Rust for the back-end. Personally I try not to use FFI because it adds complexity and ugly code, tracking object pointers, I'd rather just write pure Dart code.
airstrike 1 hours ago [-]
iced is cross platform, there's even WASM support. lots of Rust crates are.
mobile and desktop are not different platform but different devices altogether that warrant separate designs IMHO
debarshri 2 hours ago [-]
TIL egui. Reminds me of java swings.
pizzalife 5 hours ago [-]
I like egui a lot, but I haven't figured out how to not get blurry fonts in macOS/windows. If anyone has a tip I'd appreciate it.
butz 6 hours ago [-]
I wonder what is the difference between binary and libraries sizes for Flutter and egui. My guess would be about tenfold reduction in size on egui.
12 hours ago [-]
dark__paladin 8 hours ago [-]
I'm not a UI dev but I have messed with Qt some. Does egui or some other rust framework the same native look that Qt does?
Honestly, nothing beats QML for UI development. Such an underrated technology.
lazypenguin 8 hours ago [-]
QML is nice and the bridges project could bring it to more languages. https://slint.rs/ Is similar but written in Rust although.
mhast 5 hours ago [-]
After being stuck in XML land for making UI for almost two decades I couldn't be happier to leave it behind.
Spreading your code over multiple languages means you now have a bunch new fun edge cases to deal with when things get stuck and don't update correctly. With everything in one language that means all debuggers and other tools work the same regardless of where in the app I'm debugging.
I've found it fascinating to see UI building come full circle. I started in code (C), then using various XML schemes and now back in code (Kotlin, Flutter, Swift). But a big part of why it's nice now is because C is a pretty horrid language for making modern applications.
jcelerier 4 hours ago [-]
> After being stuck in XML land for making UI for almost two decades I couldn't be happier to leave it behind.
this is completely unrelated to what QML is.
QML is a complete language which allows to build both the application logic and the layout, which extends javascript with native reactive data binding. QML+QtQuick is equivalent to Dart+Flutter, or JS+HTML+CSS+React for instance.
I'm a bit concerned with Egui gaining in popularity for general purpose GUI applications. It's leading to feature bloat, and probably more overhead. The stated goal originally was that Egui should use less than 1% of main thread frame time.
Originally, Egui was completely one pass. The API looks more general than that; you can align things against the bottom or right, and get things above or to the left to adjust. But originally, that didn't work. You pretty much had to lay out widgets down and to the right. This is fast and simple. Lots of stuff didn't work, such as scrolling text boxes with line wrap.
But users doing ordinary GUI work are demanding more and more layout features, and won't stop until they get browser level layout. Overhead is increasing.[1] This is a problem in Rust game land, which is tiny. At some point, someone may need to fork Egui and create Egui-lite.
[1] https://github.com/emilk/egui/issues/7059
If your UI lib is not doing scrolling text boxes with line wrap, can't have different alignments, doesn't have a solution for context menus, then what good is it?
I remember that I essentially had to code it myself a few years ago, but I can't remember if it was egui or imgui.
I guess you worry that the feature creep dilutes the maintainers' focus, but opening it up to a broader audience might get access to more contributors.
To some extent, yes. Here's an example.[1] So many features have been added that the unit tests were taking too long. So tests were switched to use a faster allocator. That won't even compile for cross-compilation from Linux to Windows.
Because tests won't run, chasing down other cross-compilation bugs got much harder.[2]
This is the price of feature bloat. Core stuff is breaking and not getting fixed as cool features are bolted on. Currently, 799 open bugs. The technical debt is building up.
[1] https://github.com/emilk/egui/issues/7033
[2] https://github.com/emilk/egui/issues/6847
Back in 2023, this created a bug where a text box was misaligned on alternate frames.[1] Amusingly, I tried to capture a video of this, and the 30 FPS video looked perfect, because it was capturing only alternate frames of 60 FPS refresh.
Bugs in layout can be very strange in Egui.
[1] https://github.com/emilk/egui/issues/2810
Originally HTML was one-pass. Until they added tables. And tables require at least two passes to lay out.
There's only so far that you can take one pass rendering
Right. The whole point of Egui was supposed to be that it was a game renderer, a text and button overlay on the game graphics. Not the entire screen. That's why it's immediate mode. It's supposed to redraw on every game frame. Most UI programs don't need or want that.
But it was better at the basics than anything else in Rust, so it caught on for routine non-game programs. And here we are.
Flutter answers questions about more robust UI.
It's good that you chose the right tool for the job and more people should know that there are options. But fundamentally I'm most motivated by the possibility of a robust UI framework made from first principles to be as low friction as egui but with the accessibility, performance, and visual flexibility of stylable retained mode guis.
Raph Levien and the xilem project might be getting us closer.
[Edit: although the standard accessibility criticisms apply to my application; although that's more of an issue with my implementation than an indictment of immediate mode generally.]
Imagine you have a to-do list of 100 items. What happens when a remote user drags and drops item 100 to lie between items 1 and 2? In retained mode, that's clearly communicated to the UI toolkit; the widget representing that todo is told to change its position in the list. In immediate mode, you can't just destroy and re-create the a11y tree on each render. You need some kind of tree diffing algorithm to figure out that it's one op (move item) instead of ~200 ops (change the name and checkbox state for all items between 2 and 100).
You don't lose anything.
This is but my opinion, but toolkits tend to be opinionated piles of **. Talking directly with the GPU to paint stuff is often just saner to me.
Over my years making UIs I've found most of the bugs you get is due to incorrect state handling in applications. Having a framework you use which is opinionated and helps you solve that is pretty nice. (If your UI requirements are such that you need it.)
Accessibility and keyboard shortcuts are of extreme importance.
By the way once upon a time, visual studio code I think it was, was using like 20% cpu when idle just because of the blinking cursor, fun.
This can be problematic, e.g. some of the sensor interfaces I have, I want to always display correct data, even if not focused. So, I have to decide if I want to have old data shown in the background misleading users, or have a per penalty from constant renders. Or try something else to be clever. (Maybe have it update at a low rate if not focused? I think that's the move...)
sounds analogous to manual memory management
This is also mentioned in the gui docs here https://github.com/emilk/egui#why-immediate-mode:
> egui only repaints when there is interaction (e.g. mouse movement) or an animation, so if your app is idle, no CPU is wasted.
https://www.egui.rs/
Reactive mode is the one you are looking for.
I recall the author posting an imgui update saying this will be an officially supported mode, but AFAIK it's still not the case. Otherwise I would be building all my applications with imgui going forward.
Re-rendering the screen, even if it's fast, incurs a lot of memory bandwidth to draw everything and swap framebuffers etc. Not something you'd like to happen on mobile, in particular. Just because the waste is "small", doesn't mean it's acceptable.
It's not perfect, but I don't know if there's much on the market that addresses robust UI and single code base as well as Flutter.
Very open to other things that are not more complex than Flutter to accomplish the single codebase to multi platform solution it does provide.
I guess it makes sense since immediate mode focuses on speed and applications like games, but if only there was best of both worlds.
Because web's "native UI stack" is almost non-existent for actual UIs. This has started to turn for the better only very recently: https://open-ui.org/
Flutter, which does its own rendering of controls, needs to implement a lot of accessibility features by itself.
For my part I have some accessibility needs that typically aren't well supported by immediate mode GUIs. And my personal take is, this is 100% fine. If you're working on a thing where an immediate mode GUI toolkit is even a realistic option, you're probably also in a situation where it's exceedingly unlikely that making your hobby project or prototype or whatever harder to work on will cause a net increase in humanity's overall sense of wellbeing.
And if something comes up and you do end up needing to make changes for someone else's benefit, hey, good news, immediate mode GUIs are really, really easy to hack on.
Not sure that I'd recommend this approach to everyone. Protobuf code generation can be finicky to set up, but I'm doing it so that I can access go's rich array of libraries in my app.
My music model is all Protobuf messages, which go from Dart/Flutter land to Kotlin/C/Swift/JS audio backends on target platforms. I also use Protobuf for saving and sharing. It’s been incredibly resilient and performant.
I used proto buf with rust, I had a rust client that spoke to my flutter frontend via dbus. The rust client connected to my remote server via a web socket and all messages were wrapped in protobuf and sent as binary. Made everything a lot more concrete... But it basically forced me to build my own much shittier version of gRPC. Since, if the wan for your network was every killed the client was notified too late and you'd end up with missing messages if the network buffer got filled. We added a message id and acknowledgement process with sqlite backing up each message.
I still have nightmares about why I built that.
I used to use protobuf but now I just use JSON, over stdin/stdout on desktop. It’s honestly quite good.
Personally I wish we could just use UNIX sockets for "localhost-only TCP", but software support is just not there.
I do wish gRPC allowed for easy usage of UNIX domain sockets and perhaps named pipes, however. Sometimes all you need is IPC, but in my case, I'm happy to have remote usage builtin.
Can you expand on this OP? I've never had problems with `setState` nor "lasagna code" in Flutter. From a quick search I mostly seem to find questions from people who are still learning Flutter and getting basic things wrong.
Pros
- Solid widget set
- Easy to get started
- Less state management
- Easy to make custom widgets
- Active community and crates (e.g docking view, tables, etc.)
- Fast to build new Ui
Cons
- Harder to do layouts (has multipass and some flexbox crates but still hard and compile loop makes it slow to iterate)
- Bring your own architecture (no restrictions on how you build your app so easy to make spaghetti if you’re not careful)
Egui is currently my favorite Rust UI crate although Slint and iced are also interesting.
https://github.com/iced-rs/iced/pull/3000
No quick and easy drag&drop just yet, but IDE support for live preview rendering makes it come pretty close. I do long for the Visual Studio GUI design days, but things aren't as barebones anymore as they used to be in open source Rust land.
IMGUIs are almost always relegated to debug UIs and single devs because its actually terrible to maintain something that binds presentation and business logic like IMGUIs often do (and when they don't they lose the simplicity).
When hand-writing XAML or similar, it's great to see the UI created live. Like editing markdown and seeing the preview, versus editing markdown and not seeing the preview.
You can see the demand in the sheer number of WYSWYG editors for the web.
But for development, basically all the big players stopped trying or died for other reasons. I just think no-one's got the will to try it.
I think it could be a huge opportunity for someone. Right now, with AI coming to the fore in development, seems to be when it would become absolutely killer for less code orientated people making their own apps by adding/dragging controls around and telling an AI what each control should do. All without a programmer involved. The AI could even "solve" the hard problem of a good responsive WYSWYG editor by making assumptions of how the user probably wants the controls anchored.
So I think that's the market we'll see a WYSWIG editor emerge again for.
I would add that a large part of the push away from it came from not having dedicated design and development teams. Is, I think, why industries such as gaming have stuck to a lot of these workflows. You have art designers creating the assets and hand them off to an integration team that will get them into the game. Tooling is specifically made to integrate the art and the program.
In the web, we seem to have tried to converge all of that tooling into the symbolic text. Works great when it can work. But it greatly limits what you can graphically do. And is largely why we don't design things graphically anymore.
These all go direct to code instead of XML or some other extra layer of code.
What I would probably focus on is better integration with Figma and similar tools. Use that to do the WYSIWYG part and then generate corresponding code (possibly with LLMs).
The biggest limitation you tend to have in WYSWIG is that at some point you really need to have the true data the user sees to ensure everything looks good. That becomes a bigger hassle than coding the UI manually. (Particularly when doing multi-platform things.)
Like, why aren't more big projects use accessibility as hot reloading if those are so great?
Or, a simple illustration to your reliability point - part of the reason the files are hard to read is because XML is an atrocious format. And also tools like VS aren't even smart to preserve user formatting, so you can't even manually make it easier to read. Why hasn't it been changed in so many years?
However, updating the DOM and then turning the DOM to an image (i.e., rendering it) still has an indirection that using canvas/webgl/etc. don't have.
Both Mithril and Preact use virtual DOMs:
https://mithril.js.org/vnodes.html
https://preactjs.com/tutorial/01-vdom
I had the impression that the lack of double buffering would imply a more direct access, this the "immediate" in the name.
[1]: https://github.com/ocornut/imgui/wiki/About-the-IMGUI-paradi...
https://iced.rs
iced has some nice looking apps written using it, but they all seem "laggy" on my high-end Linux box somehow. I'm wondering if this is a limitation of the immediate mode GUIs, or something related to my system, or an issue in the apps?
For example, drag-and-drops or selecting text with mouse lag behind the mouse cursor.
I'm wondering if I'm not holding it right somehow?
which apps are laggy? iced is fast AF. try running the game of life example on release and crank to max speed. there is literally no lag
could be something wrong with your GPU. join the Discord and we'll help you debug
https://github.com/slint-ui/slint/blob/master/FAQ.md#licensi...
I only mention this because those constraints are notably more restrictive than the vast majority of the Rust crate ecosystem.
I take no particular stance on whether this is a fair or good practice or about the technical suitability of Slint beyond this concern, I just think it's a hurdle for most people so they should be made aware early and often.
Honestly, it’s a bit sad that for some, using libraries for free isn't enough, they also expect to do so without even mentioning the project.
For my use case it was easier to get up and running with a TUI toolkit (ratatui in my case). Plenty of limitations there too alas and I finally landed on Qt…
Makes sense to use a primitive instrument to satisfy primitive needs, those eschewing a lot of extra complexity.
Though if some funding does fall through for better gui, isn't that a risk of having to do another switch?
How is shipping egui apps vs flutter. I'd imagine that especially shipping a rust integration with Flutter might be a bit of a pain
I liked the DX with the tools and the `rsx!` macro. The use of `#[cfg(feature = "server")]` to define server-side code is interesting, it lets you keep a shared codebase for frontend and backend, while still controlling what gets compiled to WASM for the client.
[0] -- https://dioxuslabs.com/
[1] -- https://blazingboard.ch/ (not mobile friendly, sorry)
mobile and desktop are not different platform but different devices altogether that warrant separate designs IMHO
Non-goals
* Become the most powerful GUI library
* Native looking interface
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -s ./your_program
is memory leak?
Spreading your code over multiple languages means you now have a bunch new fun edge cases to deal with when things get stuck and don't update correctly. With everything in one language that means all debuggers and other tools work the same regardless of where in the app I'm debugging.
I've found it fascinating to see UI building come full circle. I started in code (C), then using various XML schemes and now back in code (Kotlin, Flutter, Swift). But a big part of why it's nice now is because C is a pretty horrid language for making modern applications.
this is completely unrelated to what QML is.
QML is a complete language which allows to build both the application logic and the layout, which extends javascript with native reactive data binding. QML+QtQuick is equivalent to Dart+Flutter, or JS+HTML+CSS+React for instance.
https://www.qt.io/product/qt6/qml-book/ch04-qmlstart-qml-syn...