Hacker News new | past | comments | ask | show | jobs | submit login
Why is building a UI in Rust so hard? (warp.dev)
111 points by osener 11 days ago | hide | past | favorite | 125 comments

Raph Levien, who's behind Druid and Xilem (https://raphlinus.github.io/rust/gui/2022/05/07/ui-architect...) UI frameworks, recently gave a talk about very similar issues. Slides here:


The first link especially is super insightful, thanks!

Thanks for sharing this! Especially for linking the slides and not just the video.

I gave up and started using Flutter with flutter_rust_bridge for business logic. I'm convinced that UI development from scratch simply cannot happen without a large company backing the project, giving it time and money. Flutter took over ten years and likely millions of dollars. HTML, CSS, and JS / TS? Likely billions.

This is because simply building the UI toolkit itself is usually not a prime motivator for a startup, they want to work on their differentiating features, not on reinventing the wheel. Of course, if the startup is a text editor or other such UI heavy app, then it may make sense to reinvent the UI wheel. Figma showed this successfully, and perhaps Zed and Warp might, too.

Oh, flutter + rust seems like a great combo. (Because Flutter seems great for UI work, but Dart is very meh for everything else.) Have you tried Tauri or some other Electron-like alternative by any chance? How do you like Flutter+Rust so far, and what's your "baseline"? :)

I too am interested in the flutter aspect, but I just recently worked with Tauri as part of a rewrite project and it was a decent experience. There are still some rough edges and small gaps, but overall it’s pretty well done. Plus, when you’re ready to ship your app, they give you tools that make packaging and code-signing very easy. I would recommend it if you have any interest in it.

Compare this to my experience with iced, where I discovered that I love the elm architecture, but dealing with the UI parts became exponentially more complex the larger it grew, so many undocumented or under documented components, plus upgrading between minor versions would cause breaking changes that weren’t always easy to solve because of the lack of documentation or examples.

I like Flutter and Rust, it's pretty nice. I actually like Dart as well, it has some very interesting features. I've used Electron and Tauri a bit before but I didn't like that it still wasn't "native," it still used a web wrapper.

Recommended reading for everyone that doesn't get how traits are just yet another kind of OOP.

"Component Software: Beyond Object-Oriented Programming"


"Authoring ActiveX with VB 6"


"Traits - Composable Units of Behavior"


"Working with Protocols"


Thanks for the links.

Container. Component. Context. Graph. I would think a "wonderful language" such as Rust should have no problem with such a basic conceptual setup, but apparently not. I personally am solidly in the adaptive components camp, specially for things like UI.

If you know Rust (I don't), curious if the monadic approach could work, propagating the state as a parameter.

to that point, traits themselves originated first in smalltalk correct??

Not originally, but they were added after Smalltalk-80, one of the links above has the related paper.

They exist now in Squeak and Pharo, both originally based on Xerox's Smalltalk-80 image.

That's quite weird. These traits don't look like rust's traits, which really are a port of typeclasses from Haskell. I think the section about scala illustrates this well because scala's "traits" are an OO construct, but now scala 3 also" has typeclasses. So... Rust still isn't OO.

Ah, trying to go down that route?

ECOOP 2009 proceedings paper from a certain Simon Peyton Jones.

"Classes, Jim, But Not as We Know Them — Type Classes in Haskell: What, Why, and Whither"


Sadly it's paywalled. Care to enlighten me? If inspiration came from smalltalk and not prolog then great, you win.

I haven't done any UI work in Rust, have used the language sparingly on the side.

But while reading the article, I was thinking "You're modelling the tree wrong! The memory layout doesn't need to know that it is a tree!" - gladly we came to the same conclusion.

The funny thing with this pattern is that Rust is much more loose when it comes to modelling with hashmaps and vectors. You are essentially creating user-space references and maintaining them with your own logic.

You're basically circumventing the borrow checker, but also a lot of other problems as you encapsulate the maintenance of these references within your tree / graph data structure.

But in a sense it's cheating! When you give me a key to a hashmap, do _I_ know whether the thing is there?

But doesn't maintaining references using a hashmap mean that you've got to cleanup, which is basically (the hardest part of) memory management?


But the cool thing with laying out your graph like that, is that it has a relational character to it.

You’re essentially dealing in tables and (one/many) to many relationships.

You have a birds eye view of where your entities are allocated and how they are connected.

You still need policies around how you clean them up (remove an entity) and how the edges are affected. But you can reason about that in a similar way as you would in a relational database.

That does not feel like advantage unless you can do relational algebra on it all, though. Without that, it's more like dBase and similar languages of that era, where you had to manually juggle tables and cursors. People did UI that way too, but there was a reason why the OOP approach with object graphs and references quickly became dominant once it appeared - it's still a much more natural way to model this.

You're not circumventing the borrow checker though. You can only access a hashmap/vec entry if you have the right borrow of it's container. Unless you play around with unsafe, the hash map entries that stay in the container will live at most as much as the container.

This is what the borrow checker does. The index is just for doing an If let Some(entry) = map.get(&ident) {}

and not fail if it does not exist. Do you want to keep stuff alive even if they are removed? You can use reference counter wrappers (Rc and Arc) just fine.

The right pattern for graphs etc in vectors and maps is that the owning struct/type is responsible for keeping its internal state (indices it knows to exist) consistent. But that's not a memory safety issue, it's a logic issue

> But in a sense it's cheating!

Once you start cheating you might as well write yourself a garbage collected language and use that to write your UI library.

I'm not a rust developer, but I see all the signs and scents of somebody who detects the truncheon and the trap.

My guess is that you're adrift in a continuum made by somebody else who started with one goal, but found an ancillary surprise benefit worthy of persisting under the umbrella of the previous illusion. Bricks kept getting put down, the pamphlet never changed, then bam there you are.

I wager you're right in the mix before former turned to latter.

Sorry, I read your comment twice but I have no idea what you're trying to say.

Me too so I asked ChatGPT to rewrite his comment like a high school student would write :

ChatGPT: I'm not a rust developer, but it seems like you know what you're talking about when it comes to detecting problems and traps.

My guess is that you're stuck in a situation that someone else created. They started with one goal, but found another good thing that they wanted to keep doing. They kept building and never changed their plan, and now you're stuck in the middle of it.

I think you were there before things started to get weird.

Not sure why your comment got downvoted. I’m also not sure I really understand what you’re saying, although I get the hunch that it might be a valuable description?

Maybe it turns out web and electron UIs took over the world because web technologies are just a better way of building UIs, and everybody who tries them in earnest realizes it.

How about "Every GUI toolkit out there trying to avoid using web tech is going to end up implementing a half-baked implementation of CSS", to coin a phrase.

Not really. The problem isn't about stylesheets. For the context, I have worked with Qt, QML, Gtk, jQuery, Sencha/ExtJS, React based codebases at various points of time in my career. Qt, Gtk both support stylesheets and no one complains. Everytime i had to deal with web frontend issues, I keep getting frustrated about how we are trying to make "Application UIs" out of what was meant to be a "Document description framework". Be it in Layouts. Be it in debugging. Be it when creating custom widgets/elements.

"You want a button? you have to style a div to get what you want". "You want to center an element vertically? You have to use a table. You have to use these css hacks." "You want to debug the component you've written? Enjoy diving through the div soup".

Of course, there's nothing stopping us from being able to use just a Canvas/WebGL/etc.. based frameworks. Hell even the imgui, qt etc.. have webassembly/webgl targets. But so far, they seem to do badly when it comes to content addressability, accessibility and search engine optimization.

The only good things I have to say about electron: They have decent free tooling that makes producing cross platform binaries easy/easier than the native alternatives. Accessing http resources in javascript is nicer than trying to do the same in C++/Java/etc... The latter is a very important consideration in this day and age.

Your anecdote about the button and vertical alignment doesn't really hold. Vertical alignment has been a solved problem for many years thanks to flexbox. And obviously, use a <button> tag to make a button.

> Of course, there's nothing stopping us from being able to use just a Canvas/WebGL/etc [...] But so far, they seem to do badly when it comes to content addressability, accessibility and search engine optimization.

In my experience the key to solving accessibility etc, when building out a canvas-based web UI, is to work with the DOM instead of trying to replace it. Use <input> to control the placement and display of graphical elements, <button> elements to start/stop animations, etc; make good use of DOM events to track user movement/interaction across the canvas; tie clickable actions to real <a> elements instead of trying to reinvent them. Graphical text also needs to be reflected back into the DOM. Good use of ARIA also helps. Etc. And don't be afraid to tap into CSS --variables or even HTML data- attributes: not everything needs to be defined in the JS (or WASM-enabled language of choice) canvas code if the end result - a <canvas> UI or infographic - is destined to live in a web page.

Proof-of-concept of an accessible design system: https://codepen.io/kaliedarik/project/editor/DVeMVj

Proof-of-concept of an accessible set of related graphs: https://codepen.io/kaliedarik/project/editor/AMVKPx

I couldn't agree more, html was designed as a simple way for users to create documents, not interactive applications. IMO stylesheets are the only good feature from html worth pulling into the app ecosystem, but otherwise I really dislike the trend of bringing web technologies designed to solve the limitation of web pages or stateless servers into desktop/mobile application development.

> how we are trying to make "Application UIs" out of what was meant to be a "Document description framework"

We try, we can, and we do. Successfully.

> "You want a button? you have to style a div to get what you want". "You want to center an element vertically? You have to use a table. You have to use these css hacks." "You want to debug the component you've written? Enjoy diving through the div soup".

Honestly I don’t think you’re entitled to an opinion on this given you obviously haven’t done anything web related in the last 20 years. I mean, even <button> was there from the beginning. Flexbox layout itself is almost 10 years old now. CSS hacks are mostly unheard of since the death of Internet Explorer 9.

> We try, we can, and we do. Successfully.

My point is not that you can't do it. It is about what kind of abstractions people have hacked past to beat a document into behaving like an application.

That's why I think every couple of years people keep reinventing the wheel to accomplish the same basic things. JQuery-Ui, Sencha, Angular, React, Vue, Svelte etc... Inline styling was a sin. Then it's the recommended practise. Not even sure what's hip these days in what framework.There is a reason why your actual application abstractions get lost when you inspect an element in developer tools.

I'm well aware of button tags and i am also aware of the reasons why people styled div and anchor elements to behave like buttons in the codebases I've dealt with. They had good reasons why they did those things the way they did.

If you reread my above comment, You'd see how I've also mentioned the tradeoffs of actually using proper ui/application development libraries and frameworks to make "Web Applications".

But if one is making an electron application, search engine discoverability and content addressability bring absolutely nothing to the table and one might as well use a more appropriate framework.

Successfully for whom? As a user, I find that when a desktop app is using a web stack like Electron, that's one of the best predictors for poor and inconsistent UX.

>"You want a button? you have to style a div to get what you want"

No, you don't, there's a <button> tag. If you don't like the default button style, then yes, you'll need to style it. But that goes for any UI framework.

Except that is usually because many don't get how native toolkits work.

Ancient knowledge lost to the druids in the mountains and dead trees instead of TikTok tutorials.

This mage will always pick native over Web when given the option, even though Web has paid the bills most of the time since the last 25 years.

> native toolkits

I get them, but I'm just not interested anymore with 3 desktop and 2 mobile platforms to think about. Sure it makes sense sometimes, but this should be fun.

Not everything needs to be cross platform.

I just want the most people to use my stuff with the least extra work and maintenance possible. It is personally important to build a future where OS and architecture are not a factor.

Most of the software doesn't make it on one platform, let alone on many.

Im releasing on 39+ platforms. https://github.com/donuts-are-good/bearclaw for example releasing using https://github.com/donuts-are-good/release.sh

Great, most of them are irrelevant, will it even get 1 user on each of them?


Is that something we should be proud about?

Why not? Not everything has to be success.

Delphi designed in the 90s is still far superior to any web technology for building UI - you can make a complete standalone app in a few hours instead of weeks. IMO JavaScript was pushed by some large corps in order to commoditize developers and also because that was about as much programming as many decision makers were capable of understanding. Now we have the Node.js/React/Electron cancer everywhere making simple things overcomplicated for 99.9% of use cases.

Your comment is an example where people have no idea what they are talking about but just making things up.

"In a few hours instead of weeks" I'd argue that the web stack only takes less time, not more.

JavaScript is popular because developers like it, because it works well, not because some "large corps" "push" for things to happen. There are more than scattered evidences to show that.

Next time, come up with something better and more convincing when hating the web stack.

JavaScript is popular because people like half-baked hacky things that give them instant rush/feeling they can do something (i.e. show something basic in a browser). So much effort was spent on painting a lipstick on this pig or to replace it but nothing succeeded unfortunately. It's the equivalent of some fast food in mental domain. If I wanted to damage programmers' minds I would push for this atrocity to become a universal standard. The quality of most node.js modules is horrible which never disappoint in reinventing existing things from other languages/frameworks in inferior ways.

> Delphi designed in the 90s is still far superior to any web technology for building UI

Then where is it?

Also, I can make a standalone app in a few hours using Electron. I guess it would take me more than a few weeks with Delphi, given that I don’t know anything about it. So your point might just be that you know Delphi and not JavaScript.

>Then where is it?

Of all people, tech workers and enthusiasts should know that being superior doesn't ensure survival.

It depends how you define superior. I believe Electron and web technologies are superior for UIs given their pragmatism and ubiquity.

Are there even Delphi enthusiasts still, or is it just nostalgia? Would the people that claim Delphi is superior use it?

> Are there even Delphi enthusiasts still, or is it just nostalgia?

There are.

There is a major commercially relevant DAW produced in Delphi. You can figure out which one.

> I believe Electron and web technologies are superior for UIs given their pragmatism and ubiquity.

This opinion is questionable given a clearly narrow view. Outside of this bubble they aren’t ubiquitous.

There are plenty of LOB apps still used and maintained in VB6. One of the most heavily used applications in the US federal government is a C++Builder app (the C++ RAD counterpart to Delphi) - it is a piece of crap, but that’s a factor of the authors not the language - and when it was first released more than 20 years ago it started up in a few seconds on hardware at the time with slow spinning disks! Looking at the vast majority of LOB web apps - nothing has gotten better on that front.

Wow, FL Studio is written in Delphi? The UI feels like from some futuristic alien spaceship!

Murdered by Microsoft, like many products and companies which dared challenge them. https://www.cnet.com/tech/services-and-software/use-cnet-sho...

One of the employees they lured away was Anders Hejlsberg, former chief architect of Delphi, which built C# at Microsoft. WinForms had an uncanny resemblance to VCL.

Before that Microsoft had tried to extend-embrace-extinguish Java with J++, but got sued by Sun into submission.

MS were utter scum back then, but Borland’s mistakes certainly didn’t help either.

Hours instead of weeks? What makes you assume that? An experienced web developer can iterate pretty damn fast.

I can understand the appeal and advantages of using native GUI tech. Really. But there is a reason people use stuff like Electron/Tauri/Wails. Web tech has seen so much investment, and as a result, you now basically have a app platform that runs anyhwere, offers a huge ecosystem and a great developer experience. Which I never found to be matched in any other GUI toolkit.

If there was a GUI toolkit that offered me all of this without requiring the bloat of a browser, then I would switch in an instant. It's just not there.

I was specifically mentioning building UI, i.e. the process of creating a set of screens with events to carry out the required functionality, which was what Delphi shined in. Web tech is about building distributed apps, so while you might repackage them as desktop ones using Electron, it's a massive overkill for 99.9% use cases and thoroughly suboptimal. Yet there aren't any GUI builders worth anything after 20 years of web tech and using libraries like React just increases cognitive load instead of reducing it by being unnecessarily verbose for little benefit.

If I build a desktop app using one of the above-mentioned technologies, there is almost nothing "distributed" about it. HTML, CSS, Javascript. Which is where 99% of my UI building happens. The only thing "distributed" what comes to my mind and what I think you mean is what would be an API call in the browser, to fetch some data that the frontend needs. The equivalent in Electron/Tauri/etc. is usually some bridging API that you can call instead.

I never missed any GUI builder. Browser dev tools are phenomenal IMO, you can drag&drop elements across your layout, change any part of your styles and instantly see the effects, measure rendering performance, memory consumption, debug your Javascript or simulate different screen sizes.

About React, nobody forces you to use it. There is a myriad of frontend frameworks, at all levels of complexity. If you feel your app is so simple that you don't need any framework, you can do without. Frameworks (and again, there is a huge world outside React!) came up because they make managing state in complex UIs easier.

In Electron apps you still have the boundary between frontend and backend, that means it's in its core a distributed app. If you don't like GUI builder, that's a fair opinion, but I do and don't want to waste my time on textual descriptions of what is essentially visual, and don't want a Figma subscription to get some half-baked version of that either. Avoiding React equals to avoiding 95% frontend/fullstack jobs these days so it's only theoretical.

Far superior... at making basic 90s UIs that nobody else wants today.

For better or worse, but the reality is nobody wants them anymore. Branding is a thing. When a client wanted something different you used to tell them "You can't have that" and they had to take it, because there was no other option.

The instant web enabled and normalized arbitrary UIs, "You can't have that" Delphi people simply went out of business. Because it turned out Delphi was far inferior at doing what people actually wanted.

> The instant web enabled and normalized arbitrary UIs, "You can't have that" Delphi people simply went out of business. Because it turned out Delphi was far inferior at doing what people actually wanted.

What people think they want and what would make them happier and productive in the long run are different things. They buy junk food and complain they don't feel well. They buy Marvel movies, but in the long run stop going to the theater because movies aren't interesting anymore. Modern web apps are basically the incarnation of that principle.

Are people really happier and more productive with shitty web apps? Because it seems like everyone complains about Slack, Teams, etc. Google Docs certainly doesn't have the die-hard fans Word Perfect still has. Apple still collects quite a premium remembering that people don't know what they want and need people with judgment to make decisions for them.

“Far superior... at making basic 90s UIs that nobody else wants today. For better or worse, but the reality is nobody wants them anymore. Branding is a thing. When a client wanted something different you used to tell them "You can't have that" and they had to take it, because there was no other option.”

Were you actually there in the 90s and 00s or are you just imagining how things could have been?

I personally developed fully skinned UIs in Delphi’s cousin, C++ builder on Windows in the late 90s and in the 00s. In addition to that, VCL apps had a rich palette of drag & drop widgets, including commercial products that were better than anything the competition was offering, including Microsoft.

I used a lot of Windows apps over the years and literally everything from custom windows shapes, colors and background, to custom widgets and cursors, etc I’ve ever seen was possible to develop in Delphi or C++ builder.

”The instant web enabled and normalized arbitrary UIs, "You can't have that" Delphi people simply went out of business. Because it turned out Delphi was far inferior at doing what people actually wanted.”

Delphi was mismanaged by Borland, sabotaged by Microsoft and they charged a ton of money for the software. Starting with WinForms and C# MS finally had a reasonably competitive alternative to offer.

The web had nothing to do with Delphi’s decline. In the 00s we used a combination of back-end languages with some JS for enhancement and Flash for special cases or multimedia-heavy sites. Macromedia Flash remained the most capable web-based technology for a long time after Delphi was already in decline. As a former Flash developer, I can say confidently that Flash and Delphi/C++ Builder served different use-cases and were not competing with each-other.

It's not about styling, it was about how quickly one could develop a complete app by just following a few simple examples in docs. VCL + IDE literally guided you with very few things to learn. So a person uninterested in building UI but in the core of an app could build one in an afternoon, which is not possible unless somebody is an expert in web frontend development, wasting time/effort that could have been spent better elsewhere. I am glad I escaped frontend hell (I used to work on some web standard myself) and pivoted over to ML.

Speaking for myself as a user, I want more basic 90s UIs that work in boringly predictable ways throughout, and less "branded" apps with weird colors and weird UX patterns because the designers (or whoever is ordering them around) are showing off for no good reason. On top of that, this trend killed a lot of customizability in UX that we took for granted for so long, like the ability to change UI colors and fonts system-wide - i.e. it took freedom away from the users. None of that is positive. So, no, it's not "nobody". I don't think you can even meaningfully say it's the majority of app users without polling them, since they generally have to use whatever is available to solve their problem, which all too often means picking the least crappy of 10 different web-style apps.

What exactly made it superior? I remember working with Delphi in high school and, in hindsight, it seemed much less powerful than web technologies.

Simplicity, great documentation, IDE that guided you, WYSIWIG, easily multi-threaded when needed. Delphi/C++ Builder is a business failure, not a technological one. No ugly hacks for things like CORS/XSS needed. Electron is basically repackaging a distributed app into a desktop one, so it's clear it's going to be way more complex than a primarily desktop-based dev system.

There’s no reason an Electron (or any other web based) app needs to be distributed. Consider VSCode. There’s nothing distributed about it.

VSCode is distributed! It supports connecting to a remote VSCode "server", so that you can edit files over SSH for example.

Of course, 99% of the time the server and client are ran together, so you don't notice it is distributed. But that doesn't mean it isn't.

They are an easier way of building UIs. Better is an opinion. Look at the sheer amount of libraries available for the web made to abstract the dreadful task of maintaining the DOM for you.

Additionally, UI work on the web is pretty much only CSS. React doesn't handle drawing elements, it delegates it to the browser. React is the easy part of drawing UIs. You could also make a fancy DSL in Rust for Qt and say "look how bad the web is my UI runs 50 times faster clearly Rust is better at rendering UIs", but we both know that's a lie.

Also, CSS is an awful wart and alternatives that have popped up like Compose's Modifier system and CompositionLocals are infinitely better.

The biggest problem IMO is the insanely complicated layout system that is the way it is mostly because it was originally meant to handle long text documents. It took a while to bolt on enough things to have decent equivalents of app-centric approach to layout that desktop frameworks have offered for decades, but it still has to integrate with everything else in the spec, and devs need to know exactly what to look for. Ditto for styling. If you compare either to XAML or QML hands on, it quickly becomes clear just how much easier it is to work with the stuff that was designed for apps from the get go.

Or no toolkit has more engineering hours as the web toolkit put in. Even with its warts, it has so many more features and tools.

Web UI are amazing to build for, and having the browser for free is fantastic, but if a dev manage to get the essential features without web tech, the end result is usually better. It's most of the time snappier and better integrated.

The problem is it's not guarantee, and it's way more expensive and hard.

Hence electron being so popular.

Somebody should just sponsor a minimal browser engine written in Rust. Bet it would be uniquely well suited for it. Wait..

Building an UI is hard, even with language with good support for it. Web ui are hard. Python ui are hard.

I have been held back for years because of the sad state of desktop UI frameworks. I have recently embarked up creating my own, if only for my own purposes. It's a nightmare.

One of the primary issues is that there is no foundational cross-platform support. For creating windows, GLFW is the best bet. I should give kudos here. GLFW works and is well-documented, a rarity indeed. The forum is also pleasant. For graphics, Skia is probably the best solution, but it has problems. For example, it is 2D only, has support on a Google Group with not much traffic, and is complicated to build. The binding for it on .NET is currently not actively maintained, despite being effectively owned by Microsoft. You also give up performance. For example, Direct2D is much faster than Skia on Windows, and Direct2D can seamlessly interact with Direct3D in the same window. But SharpDX (the .NET bindings) is no longer maintained and DirectX is of course Windows only. Then you have macOS which is completely antagonistic. It is locked to an extremely old OpenGL version, and Apple may remove it at any indeterminate time. So you either build against OpenGL or start jumping through hoops in GLFW and Skia to use Vulkan and Molten to talk to Metal on macOS. Also, macOS is the only OS that forces the window management on the main thread. All window management on all OSs is on a single thread, but on Windows, for example, that thread can be any thread. Then there's Linux and the umpteen million distros and the two window managers in X11 and Wayland. There is no cross-platform accessibility library that I know of.

On top of all this, all pf these solutions have limited to no support. Most projects are ran by just a couple of people, if that. This is not a complaint against them in any way, as it is simply an observation of the reality in that support is highly, highly limited. There's also the issue that many of the issues encountered are complex and often reach across several stacks. For example, is it a bug in Skia, GLFW, the bindings to these, the OS, the graphics drivers, or from the interaction of these.

There are also very few resources and references for stuff like this.

If I read your post correctly, you might be interested in reading the readme and maybe the code of this library I've been working on (even though it's only 2D, and (purposely) not advanced 2D): https://github.com/jeffhain/jolikit/blob/master/README-BWD.m...

Thanks for the reference! That's a great README with lots of information. Curiously enough, I had already starred your repo at some point.

> For example, Direct2D is much faster than Skia on Windows

Much faster? I’m not necessarily doubting this but you have some evidence? Isn’t Skia even used by Edge? And everybody here is basically claiming that the only UI frameworks that matter are web based - so if it’s good enough for that…

Also Qt Quick - seems to cover all the platforms mentioned. Of course it has a ton of resources poured into it, but it’s there.

Qt is pretty damn easy I would say. And some Web UIs are easy too.

In any case this article is talking about the features that are unique to Rust that make it especially hard to write GUIs.

Though weirdly it focuses on lack of inheritance which is definitely not that big of a deal (Rust does have trait inheritance - you can even get full implementation inheritance using macros if you really want but I doubt it is needed). The biggest issue by far is state management because of the single ownership rules.

You can of course Rc-RefCell everything but that gets very ugly.

I can confirm. I'm regularly surprised how slow my iOS developers are at developing a few screens.

It's amazing how much we've regressed since Delphi.

And Visual Basic for all of its faults..

I started programming with Visual Basic 6 and still feel robbed that in the 25 years of programming after I never built a native GUI.

I never fully understood why we couldn't have the VB/Winform model of building GUI on the web. Is it because we need the designer skinnable GUI? With WebAssembly and CSS grid layout, could we finally get a modernize VB/Winform?

Because the web has nothing to facilitate that. Almost literally nothing: from rich components to data handling to control over rendering if needed.

So the VB/Winform model of building GUI on the web has to re-invent all controls from scratch, then all dat abinfding from scratch, then...

Sounds like an idea for a startup!

Perhaps one of the local or browser-based IDE companies could take this on too.

There are plenty of services that offers that.

Even MS used to provide that with frontpage.

The real answer to your question lies in why people don't use them much.

Because they used to produce dubious code leading to poor rendering result.

I would like to say the Web was poorly designed but that would be too generous. The Web wasn’t designed at all. It’s a hodgepodge of poorly thought out technologies hastily cobbled together. It’s a piece of technology designed to display static textual content horribly contorted to make applications.

It took decades for JS and CSS to reach a state I consider barely useable and the best we could do is apparently flexbox.

> and the best we could do is apparently flexbox.

And grid.

The contortions you have to go through to get the equivalent of early 2000 Qt's spacer items and anchors...

Ten/Twelve years ago me and a colleague would build random desktop apps using WinForms and C#, they were deployed using a network share and ClickOnce. They weren't the most elegant pieces of software ever developed, but it sure was easy to slap together a small tool for the warehouse manager or someone in sales.

You can still do all that, on Windows. As I get older and have more experience, I have come to the conclusion that some people are more interested in the technology and less so in solving actual problems. While I'm pretty happy with my career, if I were to do it all over: Windows, Visual Studio, C++ and WinForms would have been the tools that I'd have picked. We're coming up on 25 years of a fairly stable, actively developed platform with pretty good backwards compatibility.

Maybe I missed some opportunities but with my later experience and in my line of work I got pushed towards webapps and these days PowerBI. I can make those work but I feel that as a beginner with VB6 I could build forms faster than I can do now in a browser.

Also, I remember not being completely precise: I maintained a hacked together GUI build in Access VBA. It had its warts but its web-based replacement didn't blow it out of the water and took longer to develop.

React Native is a lot faster for building out prototypes but slows down when you start building more complex screens and can be very brittle to maintain over time.

I always boggle a bit when somebody measures development velocity "by the screen"

It's smoke above pinched fingers creating a bottleneck. Whether the fingers belong to bureaucracy or dev capability requires more info than I have. My bias says look at whoever has the biggest ego and the strongest opinions. They're the anchor.

uikit or swiftui?

I'm confused by the discussion of OO. Just use an enum, aka algebraic data type, if you want control over the data. You can build an extension point into the ADT for user defined components, if that is desirable. The tradeoffs of OO style vs FP style vs having-your-cake-and-eating-it aka the expression problem are well studied. (This comment is a bit cryptic. Sorry. Don't have much time right now. Might return later.)

My experience using ECS in bevy is it feels like fancy spaghetti code. I'm not convinced it's a great approach, at least on the small scale I'm working at.

>I'm confused by the discussion of OO

I don't think anyone's saying you can't do it without OO. Just that existing popular patterns for UI tend to rely on OO patterns like inheritance and classes with instances, and easy-ish namespacing and ownership concepts that map to those ideas.

So doing it without OO is harder, as it requires something different, that may be studied, but is less well explored and documented to the average person.

I recall similar discussions about doing UIs in C. GTK, for example, sort of fakes OO in C, I assume for related reasons.

All frameworks that I know for WebApps, don't rely on OO though.

React, Angular (esp. with ngrx), Svelte

Yew and Leptos don't fake oop either

>All frameworks that I know for WebApps, don't rely on OO though

Sure, though they rely on a lot of things that are only bundled with a web browser like the DOM and CSS and their concepts of namespacing, encapsulation features, etc.

Which concepts specifically?

Rust can provide encapsulation namespacing as well

Yes. Just saying there's less existing UI specific examples and material to draw from.

Please do return later and elaborate on what you mean by having-your-cake-and-eating-it aka the expression problem.

I'm super interested in this stuff and would like to hear more.

I agree with the sketch given in the sibling comment. I think this is the paper from which I learned this: https://www2.ccs.neu.edu/racket/pubs/icfp98-ff.pdf

Searching for "expression problem" should find other discussion of the problem and solutions. The two best known solutions to the expression problem are:

- data types a la carte, which takes an FP style approach; and - tagless final or object algebras, which takes an OO style approach.

Other solutions are possible depending on language features. E.g. the linked paper above uses mixins and units.

Overall I find the discussion in the original post to be a bit naive. It doesn't make the case that an OO approach is necessary or desirable. E.g. that an OO approach provides a form of extensibility that is needed.

In the FP world, if I wanted to build a UI toolkit I would start by defining by a combinator library (usually implemented as an algebraic data type) that describes the UI and then have an interpreter that constructs everything on the screen. This hides all the state within the interpreter, which makes it easier to avoid issues with the borrow checker. The OP didn't discuss this approach either.

Thank you for the explanation and linking the paper!

The expression problem is, roughly, how easy it is to extend a program without recompiling it.

OO is typically regarded as making it easier to extend the data types of a program, since you can introduce new ones by inheritance at any time. Whereas pure FP systems specify types exhaustively at definition.

FP typically makes it easier to extend the functions, since you can define arbitary more functions on the "public" type system; whereas OO encapsulates stuff and makes it harder to do that.

> You can build an extension point into the ADT for user defined components

I assume that means there are ways of making the pure-FP approach OO-like, and vice versa.

I think its nevertheless to speak about affordances here, and rust is in my view, one of the poorest DX/affordancey languages --- the syntax and semantics conspire to create lots of friction.

This friction isnt really considered in "the expression problem", but i think is very important in practice.

We should have a "frictionless expression problem" and I think that's the issue with rust: it doesnt frictionalessly extend in the ways needed by UI programming.

Thank you for taking the time to explain!

As a relatively old person, I've had a few experiences of waiting for my favorite niche language to finally get a decent GUI library. In my experience, it never happens. It's just too much work. Only the most popular few programming languages in any given moment have usable GUI options. Even something as comparatively mainstream as Go lacks a good GUI story.

Interesting that they are working with one of the Zed people. I’ve been wondering about the Ui framework they use. Opening up this framework could invite a lot of attention since they are dogfooding it in a (imho) solid product.

First of all, it is great that there is are ongoing attempts to build a new approach at creating UI with Rust. I hope it turns out into several competing frameworks with different target audiences.

I believe, you are confusing performance with responsiveness. Where a traditional mutating UI framework would happily update a widget and keep CPU idle most of the time, your approach keeps wasting processor cycles to build widget tree on demand for rendering. This could be unacceptable for devices with an energy budget (IOT, for example). So, your approach works well where loss of efficiency is not critical.

>Where a traditional mutating UI framework would happily update a widget and keep CPU idle most of the time

Is there a "traditional" UI framework that does this? Most UI frameworks are retained anyways and will build a tree (ex. Qt, Fltk); and will render at 60fps (or throttle is there is nothing to do). As far as overhead goes, I can't imagine the Rust approach being anymore expensive.

The approach of just updating and rendering a single widget is hypothetically more performant, but I rarely see it done in the wild due to how complex it can become as your UI gets more complex.

It was the standard way to do native UI on the desktop before composition became common in mid-00s. I don't recall it being particularly complex in practice, especially when the frameworks abstracted most of it away. E.g. WinForms running on WinXP would still be doing this under the hood, but you as a developer could just set up data binding and write the painting code for any custom widgets (and wouldn't have to care about it getting called at the right time).

Rebuilding your widget hierarchy every frame is overhead, and arguably wasted, but realistically it’s a tiny fraction of your application’s CPU time.

UIs are inherently about state, and a lot of state is hard in Rust. The big 'tree of state' is just awkward.

UIs are inherently async and event drive, it's callbacks over callbacks, again, harder in rust.

UIs have a lot of detail. A little screen has a lot of hidden bit of small complexity.

Rust is a heavy language that wants to treat every line of code as an existential security threat and performance.

It's really not the right tool.

Perhaps the most obvious answer is that it is may not be the appropriate language for that use case? It is like suggesting to use Solidity or Assembly to build the UI for your app.

ECS essentially uses the relational-database-like data storage. To model a tree, ideally you would have ECS but with graph-database-like data storage.

Great articles, which lead me to check out warps, which looks like a product I would use and consider paying for the pro features. Kudos

Is the challenge really Rust’s design? Or is it an ongoing case of best is the enemy of good? It seems like every UI toolkit we see is another attempt at The Perfect UI Paradigm instead of just being Rust bindings for fltk or whatever.

(Oh hey that’s a thing! https://www.fltk.org/articles.php?L1771 )

Why not have a separate language for UI that calls native rust apis?

I believe that is what Tauri is for.

the people over at https://zed.dev have done a great job. do they use something special?

Whoever designed the color scheme for that page has to be blind. But yeah, Rust's borrow checker is not designed for GUI apps.

Because building an UI is hard?

English is the new UI

Yes, with AI getting so good we'll soon don't need to look at screens to get stuff done. We'll just ask the AI.

This is a white whale for a lot of people.

http://www.areweguiyet.com (seems updates to this thing have stopped?)


The state of TUI on the other hand is better (posted recently, there are a few others):



There are many GUI libraries out there that make use of existing toolkits written in other languages. Honestly, I think that may just be the correct way to go.

Not only does this allow to use "normal" trees for setting up components, it also reuses most of the usability features.

Drawing a box and some text has been solved now. Several Rust libraries can render entire UIs with all the common controls you can think of. The downside of using these pure Rust libraries is that they seem focused more on features than usability. The created UI looks like it belongs inside a video game engine. It doesn't match any of the controls you'd expect to see, it doesn't even try to use your system's theme settings, or even the common OS conventions in some case, especially if you're trying to go cross platform.

One of the best ways to develop snappy GUIs that stick to your system's settings and themes is to use the windows crate and package Wine with your executable. Wine can emulate your system's theme quite convincingly and the Windows API solves most of the accessibility problems. It's a massive pain to develop against, but in my opinion the end result is much more convincing as a "real" UI than many of the native libraries.

After that, Qt provides some pretty good control libraries but interacting with it from Rust is a little painful as you need to choose between tons of wrappers or dropping Rust's safety mechanisms with unsafe{}.

Personally, I'm hoping wxRust gets worked out more, as its still in its early stages by its own admission m. WxWidgets solves my usability problem well enough and is lightweight enough that I think it could finally solve my UI usability quirks. Sure, you'll have the lack of safety guarantees and rely on the C renderer, but WxWidgets has been out for so long that I'm confident the types of bugs switching Rust would solve have mostly been found by now.

Rust sucks for UI, async services, language runtimes, and a couple other things because memory usage patterns of those apps don't favor Rust's memory/safety model? I mean, who would've thought? Rust was introduced as a "systems" programming language after all, and doesn't have to be everything to everybody. Rust isn't even extensively used within its originating project/org (FF/Moz).

IMHO, Rust's anti-C/C++ narrative also starts from wrong assumptions: in traditional Unix, what you're doing with C (apart from the OS) is implement the runtime of higher-level languages, but no-one has bothered to implement JavaScript or other engine with GC (let alone JIT) because committing to Rust's one-size-fits-all borrow checker just means the result can't be competitive. malloc()/free() also sucks, but its problems are only amplified by today's desire for single-process multithreaded or async backends; for one-shot commandline apps or process-per-request backends OTOH, there hasn't been much of a problem.

Rust's 'one-size-fits-all' approach and the 'rewrite it in rust' movement are due to the language's high-level flexibility whilst also being as low-level as C.

If you set out to write a new language in Rust, to escape the perceived limitations of the language, you end up extending Rust, not building a new language, and now you have Rust without the limitation you started with, and others can benefit from your work.

I've written two videos on the topic that I'd love to know your thoughts on, the first talking about Rust's universality due to both the unsafe and macro systems: https://www.youtube.com/watch?v=PuMXWc0xrK0&list=PLZaoyhMXgB...

The second a deeper dive into the macro system: https://www.youtube.com/watch?v=MWRPYBoCEaY&list=PLZaoyhMXgB...

Applications are open for YC Summer 2023

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact