Ask HN: Does Java need a modern Java UI toolkit for desktop/web?

120 points by jeffreportmill1 ↗ HN
If Java had a modern UI toolkit to create & run apps natively on the desktop and in the browser, could it rescue Java Client development?

I've been working on SnapKit for several years (+) to rescue my apps from obscurity by deploying in the browser and it's gone reasonably well, so I'm wondering whether it could be more:

GitHub: https://github.com/reportmill/SnapKit

Demos: https://www.reportmill.com/snaptea/

jeff

177 comments

[ 5.2 ms ] story [ 626 ms ] thread
Wow. This looks like something definitely worth investigating. TeaVM seems to be the secret weapon here (HN discussion from 2021 at https://news.ycombinator.com/item?id=25978053)

What limitations have frustrated you the most in working on this?

Yes! TeaVM is an under appreciated absolute jewel!

The big challenge was having to write most of a UI kit to basically abstract Swing. But there is a surprising symmetry between basic Swing+Java2D and HTML 5.

Well, congratulations for the SnapKit project so far. I have now got my project to tinker with this weekend. :-)
(comment deleted)
I'd like it if there was a GUI theme to make existing apps not look terrible.
Thank you for that - that's why my promising career in graphics design went kaput. I'll hire a professional for version X.

:-)

It looks just as it should look, ignore content-free criticism.
I think JavaFX does a good Job. However, there is always room for a better framework for cross platform UI..
So I'm a mostly-front-end web developer and I've never used Java. This looks cool; I have a couple questions:

  - How is this running without a java runtime? WASM I assume?
  - Given the performance and accessibility of modern html/css, what's the impetus behind something like this?
SnapTea leverages TeaVM https://github.com/konsoletyper/teavm to convert Java to JS. However, SnapKit provides an entire UI framework layer too, enabling app portability to other environments (like the desktop JRE).
TeaVM compiles to JS and includes the basic JRE runtime. Still very lightweight!
Oh that's an interesting approach.

I'm really into these kinds of projects because I'm trying to create a "design language" - a DSL built specifically for UI/UX designers. The idea is to provide them with something kinda like CSS, but using their own vocabulary and mental models. My thinking is that if they can write code describing interfaces in a way that makes sense to them, then all a developer would have to do is wire it up with behavior. No more handoff or recreating UIs from design mockups.

The effort is laudable, but ultimately futile. The world has moved on from Java on the client. It is now largely relegated to a backend language for enterprise applications. Nobody really wants the heavyweight mess that is the JRE on the desktop when other frameworks do a better job. There was a case for Java-based desktop apps in the 1990s/2000s when browsers were slow, desktop UI toolkits were generally terrible and lacked cross-platform capabilities. But this was then and now is now.

So no, a new UI toolkit is not going to revive Java in the mainstream.

Aren't android UIs predominantly Java?
Android's "native" UI library has hard dependencies on key components of the Android OS that go far beyond what can be provided by any random Java JVM/JRE (i.e. you can't simply use Android's UI .jars almost anywhere like we can with AWT and Swing).

Saying "Android's UI is Java" is like saying "Apple's macOS Cocoa is x86" - technically true, but belies the sheer volume of transitive dependencies.

That's true of classic Android UI, which isn't that great anyway.

The new JetPack Compose ui toolkit is cleanly abstracted from Android and works on the desktop as well.

Yeah, as are some of the most popular and modernized desktop apps. I'm always astounded by these posts.

Java has two modern UI frameworks. Swing and JFX. They blow Microsoft's offerings out of the water--while being proven cross-platform.

> Java has two modern UI frameworks. Swing and JFX. They blow Microsoft's offerings out of the water--while being proven cross-platform.

I hope you're being sarcastic there...

Swing is decidedly not "modern" at all: its active development period only lasted from 1998 ended by 2005, and saying that Swing is "cross platform" is really overselling it because it always looks out-of-place, if not downright hideous (default skin) on every platform;

While JavaFX is/was so unpopular that it was removed from Java SE and Oracle will stop supporting it by 2025.

Regarding the microsoft part, how can anything not look out-of-place, when their own settings appS have like 5 different GUI design here and there.

Otherwise, JavaFX was axed from the JDK because there is absolutely no reason to tie a frontend lib’s lifecycle to that of the JDK’s. Swing could not be axed due to the insane amount of dependencies on it, but JavaFX has it in a way, better as being developed separately.

And even though it is not huge in terms of marketshare, it is doing good with proprietary solutions, cross-platform compilation to web, desktops, and both android and ios being available.

Well, which ones. I use IntelliJ and SQL Developer. While the first one is one of the best tools in the toolbox, it still has problems with global menus, dpi and pretty much everything very platform specific. Using xfce probably doesn't help.

Truth is that the only advantage Desktop Java has over electron is that it is a bit faster and less leaky, but the advantage above Qt is only that you don't need to learn C++.

I agree with the conclusion, but not with the argumentation, which would factologically correct sometime around 2012. For example these days you have modular JVM, GraalVM, etc and a hello world Micronaut service launches for about 20ms.

This doesn't affect the uselessness of client java as competition has also improved and java doesn't offer anything extra. If you want it quick & dirty you use electron, if you want to have it nice & smooth - QT. Desktop Java is neither a fish, nor a crab in a way.

How is Java desktop not nice & smooth?
This is such a US worldview. As someone from europe, I'm still scared I'll stumble into a job where needing to code Java sneaks up on me (and quitting with leave and finding a new job is a few months endeavor). I wish it wasn't used anymore but that's far from the actual truth.
American here. The way I read that argument was Java on the desktop for UIs, not "no Java anywhere." Java has been a core part of every company I've worked for since finishing school, it's just kept on the backend in the service of APIs and the like. But other than Android UIs, mentioned in a different reply, Java isn't the driver of desktop applications, and probably won't be in the presence of Electron apps and more movement to mobile anyway.
Why do you wish it wasn't used anymore?
Code Java or code desktop Java? You can easily stumble on stuff like Spring every job, but I'd be very surprised if I started new job and it turned out I have to write JavaFX as part of it.
All your points tell you haven't a clue of how modern java works. No need to mess with the JRE, just bundle whatever you need in your executable and it behaves just like any other application. And it's not heavyweight, at least not compared to Electron and friends, which are thriving. So I don't see why that should be a concern.
Can you point to an example? I would love to download one of these types of apps and give it a try.
I think Slay the Spire is written in Java? At least there’s a mention of it on the launcher.
IntelliJ IDEA is the first that springs to mind - very popular Java app that ships with a bundled JRE. Not sure I’d call it “lightweight”, it does take awhile to boot up, but once it boots it’s a great app.
> Not sure I’d call it “lightweight”

Indeed, I'd argue that apps like IntelliJ are exactly why nobody wants Java on the Desktop. I had to buy a computer with more RAM specifically because IntelliJ uses so much. Even Electron apps aren't so bad with regard to RAM usage.

This might be true, but it's also misleading. Intellij is a pretty huge application, with a gigantic set of features and capabilities, likely far more substantial than even the largest/most complex Electron app out there.

Intellij would require notable memory and cpu regardless of whether or not it was Java. See XCode and Visual Studio for comparison, as they are probably closer to the same feature profile than something like VSCode would be. Their memory footprint and performance is not what I'd call substantially better than Intellij (and as with most comparisons of this nature, many caveats exist around which plugins/addons/features are in use).

Would Intellij have a better resource profile if it were native? Ya, possibly, but it's also possible that another language/platform would have been a significant barrier to long-term success. Not many cross-platform UI toolkits from 2000 to choose from, and many fewer have continued to be well-maintained and usable today.

I've never had the other apps freeze for 10-30s when loading for the first time during the day because it decided to index the whole project. Or completely freeze because I have 2GB of XML files in a directory I didn't even touch.
> See XCode and Visual Studio for comparison

I haven't used Visual Studio, but I think IntelliJ comes out pretty unfavourably in comparison to XCode. On my machine XCode would only slow it down when it was actively compiling (which I would expect from any compiler - it uses pretty much all of the resources of the system), whereas IntelliJ would slow it down just having it open in the background. I had to close down everything else when I wanted to use IntelliJ, or deal with a laggy system. The only other app that had a similar effect was Figma.

It sounds like your OS handles memory pressure quite badly.
VS is substantially worse than IDEA in this regard; the feature set is consistently years behind, and many actions that are instant in IDEA are long, modal/blocking operations in VS.
Additional couple GBs of RAM is not expensive. Especially for something you use professionally to make money.

It's like a carpenter using a hatchet because a bench plane costs more money.

When was this? I've been using IDEA for years and I've been satisfied with memory usage. There's actually a problem with massively increasing the memory usage such that more and more garbage builds up making garbage collection take much longer and causing freezes, though newer GC does much better here.

Also keep in mind what IDEA is doing with that memory. It's storing indexes to all your code and libraries for near instant bidirectional navigation and search.

Also be weary of supposed high memory usage with Java. The JVM will allocate memory from the operating system for the application but then not actually use it. It's doing this so that in the event the memory is needed, it's already been allocated to the process. I've seen other apps increase the overall memory load and the JVM then relinquish it's pre-allocated-but-unused memory.

Come on, you are comparing a full-blown IDE that holds the whole indexed project in memory, provides constant analysis to a TODO MVC.
Maybe if you have lots of plugins it takes a while to boot. For me, it gets past the splash screen in about 1-1.5 seconds, then it takes another 2-3 seconds to fully restore the project/re-open editor tabs etc. That's not bad for what it's doing and an app of that size. Slow startup times are certainly not a big issue anymore.
The desktop trading app from Interactive Brokers is a pretty good Java desktop app which implements its own UI.
Yep. At my previous company, the Java (server-side) builds were a lot faster than the JS / React (client-side) builds. The fat jars were also a breeze to deploy. Java is lightweight now.
JS / React build performance suffers because of a few things; sheer amount of files and code due to the normalization of small files and many dependencies, and inefficient compilers / transpilers built in Node-flavored JS instead of native.

There's projects like deno and esbuild that should help mitigate those issues, and Yarn's Plug'n'Play to reduce file amount and size overhead by using .zip files and centralized repositories. I mean it's only a patch but still.

Whenever I do a "du" on a node_modules directly, I am always amazed! How did we get here?
We said that we were adopting the Unix philosophy of doing one thing, and doing it well. While at the same time, we wanted to avoid the dependency hell that plagued other systems. So we allowed each dependency to specify its own version of dependencies. The graph grew to an unmanageable mess. I realize you may already know this, but perhaps someone reading these comments could benefit.

Every organization with whom I've been affiliated since 2017 has a fairly strict policy of dependency audit. Dependencies are NOT allowed to be added unless there's a really good reason. And even then, we pay a lot of attention to what that dependency will bring with it.

Devs complaining that the JVM is too heavyweight for client applications when electron is dominating the desktop landscape.

Satire is dead...

That's true on the other hand the state of Java desktop UI frameworks is at best confusing. I guess it's possible to write well performing Java desktop apps and yet I have a Java app that slows down my whole system and usually crashes on macOS
I use DBeaver on MacOS and it is pretty good and responsive. Only one intermittent keybinding bug with home/end.
Is the App an old POS? I see a lot of old Java Apps still around that sort of bitrotted to hell. We bitched so much about Java Apps that so many just got abandoned, even if the apps where sort of cool and/or didn’t have a replacement.

Maybe I’m getting old but I’m a bit sad for all the open source apps that where abandoned over the years because the tech stack stopped being cool.

Anecdotal, but Java is the only platform where I could download a random jar from a possibly long dead professor’s abandoned website and have a working GUI of some CS algorithm visualization with a double-click.

Hell, websites don’t hold up as well to time with all the missing links/resources.

It's much easier to write an application that crashes in C++ than in Java. I don't think the existence of whatever program you're talking about demonstrates much.
Javascript is going to the desktop with Electron, C# is going to the browser with Razor, what a time to be alive.
I think what we need is a very thin layer, or perhaps just a binding, between JavaScript, and native UI API calls. Then you could have a JavaScript non-web app with native look and feel
I'm not sure if I'm reading this right but either duktape or WebView might do what you want.

https://duktape.org/ https://github.com/webview/webview

I'm thinking of a world with Javascript, but without HTML or a web server.
You're describing the Mozilla platform's old XUL strategy, or the modern Gnome desktop. JS has permeated GTK for the last 10 years. It was a huge part of Gnome 3. For a brief moment, pushing people to start with JS for their next GTK app was an explicit strategy for the Gnome project. There was so much backlash, though, that they backed away from that position a month or two later. Had they had the courage to stand their ground, the rise of Electron might never have happened. A world with a better GTK as the go-to cross-platform UI toolkit would have been a lot better than where we ended up instead.
Or Qt’s QML.
You can make a hello-world app with JS and GTK by creating a file hello.js, typing some code in, and then running it. AFAIK, although Qt has some support for JS integration, the story is not the same. You still need to develop a traditional Qt app and then start peppering in JS where it suits you. Am I wrong?
I did a little proof-of-concept a long time ago using Mozilla Rhino + SWT apis and managed to get a small window on the screen with a few buttons with only javascript, but I couldn't figure out the api to make a simple http call...
> C# is going to the browser with Razor

"Blazor", actually.

I never “got” electron. My work is building webapps and I don’t see why anyone would want to use HTML and JavaScript to develop a significant desktop app with modern UI.

I can only assume web technologies and electron got popular because all of the Desktop platforms where trying to jump to tablets and phones and whatever else they considered new and shiny so that while web tech was a terrible stack it was at least stable.

P.S.: I sort of hope for Griffon to make a come back. Griffon framework + Groovy + JavaFX looked nice to me.

> while web tech was a terrible stack it was at least stable.

No no no. Web tech was/is terrible, but it's dirt cheap. You can hire JS hacks by the boatload, and retrofit whatever they build into an electron app relatively easily. Whereas desktop developers are few and expensive, and they tend to optimise for this or that platform or toolkit.

Electron didn't win on quality or features - it won on the back of commercial realities of the development world.

I don't think 'desktop' devs are any more expensive or cheaper. There's definitely way less of them and majority of people who know stuff like Win32 APIs are either very specialized or working on games.
Can’t set up a sweatshop as a school and have students pay to work on Win32 apps.
That's what a lot of companies did 10-15 years ago in Poland. Sometimes it was Delphi. Of course, the applications were shitty, but also a lot of web is shitty.
Basic supply and demand dictates than, being fewer, they would command higher prices. Which they did, until JS ate the world.
Well, there are a number of “selling points” to electron/NW.JS or similar: reuse JS code/skills/libraries (npm) to build desktop apps; use Node.JS to build desktop apps; cross-platform. It clearly lowered the barrier and from a company’s perspective front-end talent’s “reach” is expanded.

Even way before they came out I wondered why more native apps didn’t just reuse HTML/CSS at least (many did).

Of course we all know of the downsides of Electron (basically Chromium + An App in every app; ridiculously heavy-weight.

I’m fond of the webview project and Tauri, being built on top of it. It reuses the available system browser view and doesn’t bundle Node, so it’s very light.

> It reuses the available system browser view and doesn’t bundle Node, so it’s very light.

It's 'light' in terms of download size, it's not far off from Electron in terms of resource usage. Most complaints about Electron are about resource usage, not really download size (though there are some).

Very good point.
As a layout and rendering toolkit, the modern web browser is just head and shoulders above everything else in terms of features and ease of use.

As problematic as CSS is, getting things in the right place is still dramatically easier than with Swing LayoutManagers, and when you do have problems, you have great tools in the browser to explain what's going on.

Browsers particularly shine in text rendering, naturally; text styling, font selection, word wrapping, etc. are all easily configurable. You want bold text next to regular text in Swing? You either need two JLabels, or you wrap your text in <html> tags and let the embedded HTML 3.2 renderer do it.

Swing isn't exactly the latest toolkit though, is it?

JavaFX has much more intuitive layout for apps than HTML and also has CSS. So you can get the best of all worlds. HTML5 has been trying to catch up with CSS flex-box, but it's all just retrofitted and shows.

Whaaat, no way. Sure, Swing is not the epitome of a framework, but the web was famously terrible before flexbox, and it is still not as advanced as something like Apple’s constraints based layouting system.

Also, word wrapping? HTML is quite terrible to read compared to Latex-rendered text so I wouldn’t say that it is all that good in fonts either.

> Nobody really wants the heavyweight mess that is the JRE on the desktop

I mean, people seem to put up with electron these days, and the few modern JVM GUI apps feel generally better than electron stuff (for instance the all-pervasive UI latency that you get with things like vscode and slack is largely absent from IntelliJ).

That latency really is the killer. The web needs a fast UI layer separate from the DOM. I’m waiting for WebGPU to roll out and build a UI library on top of it, forgoing the DOM. But then this is just another “hack”. I wish the web had something a bit better.
The DOM can be blazing fast. Just avoid pointless div soup, and use CSS that avoids complex text reflowing when not strictly necessary.
The world is very large. Possibly most of it has moved on from Java, but I am frequently surprised by how often I encounter it in scientific applications. For example, ImageJ and micro-manager are very important players in the microscopy world, both large UI-heavy java projects, and MATLAB's UI is java based.
Isn't matlab's everything java-based?
I'm not sure... you can run it with a -nojvm flag, which turns off the ui but still gives you an interpreter, but I'm not sure if that means "no java at all" or something more specific.
SnapKit lets you code in Java but deploy as transpiled JS when using SnapTea. No JRE, just a native browser app. Try the demos, it is quite, well, snappy.
Even the one platform where Java is the native language of the UI toolkit (Android) is moving to ditch the Java language for Kotlin.
Kotlin doesn't bundle a fundamentally new/better UI toolkit. It's just another JVM language.

Most complaints about UI toolkit in "Java" are really about the JDK, its startup time, and the fact that the UI toolkit in the AWT/Swing days never closed the gap with native apps.

Kotlin would just be using the core library UI (or android UI API), so it's no real advantage.

Yes true, but the android sdk is completely written in java and this most likely will stay like this. Even some new jetpack libraries are written in java... If a newer java version would be enabled for android development, is there really a compelling reason to use kotlin?
Android’s Java is no real java, it is stuck in a strange limbo of Java 8 compatibility with some cherry-picking from fresher features, while actual Java is at 18 now with plenty of important improvements.

Kotlin compiles some of these newer features’ equivalents to java 8, that’s why it is used. But that is a failure of android, not of Java.

I think you could just say the world has moved on from client-side desktop apps. Doesn't matter much what language, the majority of applications are web-based and there are major negatives to having a client side install experience with patching, versioning, support, etc.

Yes there are still niche domains that would need a desktop app but those are probably more rare as time goes on and/or already have established players.

Client side install experience is what mobile apps have, and everyone seems to prefer them to web apps.

Web apps also have major downsides. It's easy to forget about them as developers, but for example, one is the lack of versioning. Someone pushes a new version of the app that's buggy/an UI downgrade/causes an outage and the users can't do anything about it.

Often you want an app to be local because it's interacting with local data, or local hardware, or it suffers from latency, or you don't want your data to go outside your jurisdiction, or it's doing something else where distance between you and the app is problematic.

Client side apps written using normal toolkits (not HTML) have a lot of major end user advantages, which is why:

• Mobile apps beat web apps, despite devs trying to make users accept them (recall the history of the Facebook app for example).

• HTML5 keeps sprouting features that desktop apps have had since the beginning. Filesystem access is a recent example.

Any time you want your data to be independent of the apps that work with it, web apps just faceplant.

In my view developers push web apps on users usually for our own convenience, e.g. being easier to bypass IT department bureaucracy. But there's a lot of ways to do better than web apps, and yes, the JVM is pretty good platform to do that on (JavaFX is a great toolkit for instance, and JetPack Compose is very interesting). What it needs is a great distribution and update solution.

I was mostly referring to desktop app vs. web app since the OP was talking about desktop apps. Mobile apps are a different topic but they also share a set of the similar trade-offs of a desktop app with install/upgrade and support (i.e. multiple devices/versions).

Pushing buggy/UI problematic software is a process/people problem not really a technology problem. I would bet the feedback loop for getting fixes in on web apps can be much shorter than client desktop apps (or mobile). Once a fix/change is tested we can have it out in production on a web app for 100% of users in 20 minutes.

Stand-alone apps are a great niche where the native UI kit or other UI kits that work for the problem being solved are a great solution, there isn't a need for web tooling.

On the web, regressions are a pure technology problem exactly because there aren't any chances for processes or people to get involved (other than the devs themselves). When users have more control over software rollouts they can tailor their risk profiles and tolerances to their own situations, do regression testing on their own scenarios etc. In turn that means you can offer better privacy.

An extreme example of where this matters is in the military. You cannot have an army in battle being brought to a halt because some web dev pushed a syntax error in a PHP file. You must have a qualification procedure that tests it in the scenarios that matter, which the developers may not even understand all that well.

Another example is medical software. If you push an app update to equipment in an operating theatre and a button stops rendering because the doctor had the font size wound up higher than expected, then people might die. You just cannot do that. Heck you cannot even allow it to depend on working internet. It has to be a desktop app (well, embedded, but a lot of embedded apps are just desktop apps on kiosk mode operating systems).

Now you're right that if you do push a bug, then due to all the data collection and the way browsers commingle data and code, you can fix things faster than the slower more async process preferred in the desktop world. But there's no fundamental reason it has to be that way, it's just a question of social norms. You can make a desktop app that can be force updated immediately or even on a per-screen basis. People just don't do it because often if you're writing a desktop app in the first place, it's because your users want or need more control than a web app would give them.

I guess I would start with: did Java fail as a client application because of the UI? or was it something else? (I don't know the answer nor do I have an educated opinion).
Once upon a time Java GC was truly awful. Early versions of java lacked even generational garbage collection, meaning your app would simply hang for a few seconds every now and then while GC happened. On top of this, the performance gap compared to native code was much larger in the early days.

This gave java a reputation for sluggish UIs which would mysteriously hang. In an era where new CPU generations provided meaningful performance improvements to client applications, why would a developer commit to a platform which rolled back the clock by 2 CPU generations?

There was also the annoyance of having to install the JVM. And the updater never removed old versions, so you had to know to do that manually.

Then Java 9 came out, but 8 didn't go away, so you needed both.

This is very impressive! I haven't done ui code in a while but I would have loved to have the integrated "devtools" helpers!
Thanks! It took me a long time to figure out I needed this - now I can’t live without it!
Dont be disillusioned by the negative comments. There are a LOT of Java developers as you already know. I am sure there is a percentage of them who do not want to learn another language to build/prototype UIs. Your work definitely have an audience.

Btw the demos are really good.

I’ve been a C# developer for a decade, before that I worked with Java. These days I mostly work with Typescript as we use it both for our client programming and for our backend which increasingly consists of Node micro-services running as Azure functions. If you had told me that I would be writing backends in JavaScript five years from now back in 2017. I would have likely considered you to be crazy. Yet here we are.

Before I worry you too much let me tell you that I’m not at all religious about programming languages. It’s just that using the same language for the front and back end is very convenient, and now that Typescript (and Node) are actually good enough, also possible. Which leads me to the point I want to make here. Over the years both C# and Java have also gotten much, much, better. But because programming languages and environments in general, have become much, much better, there is rarely a reason to chose a technology based on its tech-specs. Heresy to most people, I know, I know, but we aren’t Netflix. Our most expensive resource isn’t how much iron we burn in Azure, it’s our developers and the speed at which they can deliver reliable and safe applications.

I think it will become increasingly hard to “bring developers back” in this world. Because why would we come back? .Net has seen some really awesome innovation in recent years, and is still seeing it, and yet we’ve moved away from C# and onto Typescript (still benefiting from a lot of .net stuff in azure functions), and .Net moves much faster than Java. So I doubt it, but I hope someone makes it anyway.

Relatable comment.

Clojure + ClojureScript has been doing the "same language on front and back" as well for a long time and a lot of the developers were not working on JVM platform before getting into the language.

I think it's not a battle of languages exactly, but of battle of runtime platforms, like is now evident on the JS side as well. Kotlin and TypeScript are the mass appeal examples of this lately. But I think Clojure is the stand out one so far that is good at covering both backend/frontend and crossing between runtime platforms (JVM and JS).

I much prefer the Swing approach of having one solid framework, instead of a bi-quarterly new-and-shiny UI framework that goes straight from alpha to deprecated without ever really reaching production quality
What's the problem with Swing that inspired JavaFX and new frameworks like this one?
The non-web frontend is largely dead outside of specific use cases (gaming, for example). So embrace it.

Java does a fine job on the backend. It honestly shines there. So let it do that. And let the modern front end platform (the web) do what it's good at.

JavaFX is not bad at all but changes in licensing haven't helped its cause at all.

It's close to malpractice, however, to develop desktop applications at all in 2022. That is, you can write a web application, upload it to your server and you deployed a web application.

If you write a desktop application that's just the beginning because now you have to do the installer engineering, possibly deal with cross-platform problems, possibly deal with different versions of the same platform, etc.

Another thing we forget is that web browsers are on an entirely different level than other GUI applications because a web browser is designed to stay responsive to the user when loading multiple streams of data over a slow network. Contrast that to desktop applications where the "beachball" or whited-out windows is normal and unavoidable. Browsers are still written in C++ by the most advanced software development organizations because you just can't manage that in a managed language.

If you develop for a browser or a browser-based environment like electron you can take advantage of all that work... Even if it means using a maddening async I/O model.

I too was disgusted with electron's "bloat" but when I went looking for a cross-platform GUI framework I looked at gtk, tk, qt and many others and compared to electron it was like going from 1850s technology to 2050.

> desktop applications where the "beachball" or whited-out windows is normal and unavoidable

If desktop development is "malpractice", this is actually a clear-cut case of slander and libel.

Beachballs are absolutely avoidable, with some basic thread management - which is fairly trivial in any half-decent modern toolkit.

How come I see them all time, especially with applications from Microsoft, Adobe and other big software firms?
This is like asking why clicking buttons or links in web apps often just does nothing. You don't notice because you "know" the browser is loading the next page, you're waiting for the server and because you know that browsers don't bother displaying beachballs anymore even though the app is busy. But it's not actually any different.

If you like, structure your desktop app as two threads. One does the UI. The other does processing stuff. Exchange only messages back and forth. I've actually written a desktop app this way in the past. However it's not the silver bullet you might expect, largely because expectations users have for desktop apps are significantly higher than on a web app. In particular they expect something obvious to happen when they click buttons or menu items, and they definitely don't expect long delays simply because the backend is busy. So I ended up having to introduce some shared memory and read/write locks back again, as the pure message passing model was occasionally introducing UI stalls. In a web app you'd just ignore them because standards are low. On the desktop it's like on mobile, you have to care about the responsiveness a lot more.

Apart from the argument of different expectations discussed in the sibling comment, there is the fact that those behemoth apps you use are largely not developed with modern toolkits. Most of them are 30-year-old piles of C++ hacks, built to work on operating systems that don't even exist anymore and badly patched, year after year, to keep up with OS vendors' agendas. Unsurprisingly, they screw up from time to time.

The funny thing is that, despite thall this, often those piles of hacks are still compared favourably with Electron apps and browser-based apps.

> Another thing we forget is that web browsers are on an entirely different level than other GUI applications because a web browser is designed to stay responsive to the user when loading multiple streams of data over a slow network. Contrast that to desktop applications where the "beachball" or whited-out windows is normal and unavoidable.

Agreed that beginners using desktop GUI toolkits often make the mistake of putting long-running code in a button press callback, and then the GUI freezes.

But it's pretty easy to avoid this, so long as you know about it. If you're doing network/IO related stuff, make your callback async and await the data. GUI toolkits often have an event loop built in that can run user-supplied async code. If you're doing CPU intensive work, spawn a thread (maybe in a threadpool), and send data back to the GUI thread over a channel (the GUI thread uses async callbacks to check the channel). Not as easy as async, but often GUI toolkits encapsulate this into some kind of "Task" object for you that can take out some of the boilerplate.

Beginners make that mistake with simple applications.

It's still a chronic problem with major applications from vendors like Microsoft and Adobe because their applications (Office, Creative Cloud) have complex internal state that needs to be managed. The easy way to do it correctly is to put one big lock on the shared data structures which means a minute of beachball at boot and the app locking up periodically.

The counter to that in the asynchronous world (web browsers, electron) is that you search for something and you always see "0 search results" before the search results load. Even when I manage to banish this from an app by putting loading indicators in all the right places somehow this gets lost as soon as another developer patches something. Yet that's what you get when you trade the "dead by default" behavior of desktop UIs for "live by default."

(comment deleted)
I have been impressed with SnapKit since first learning of it.

The discipline and effort required to build the proper framework-level abstractions to be portable to future UI toolkits is extremely impressive.

And unlike some other projects, most of the demos are non-trivial, substantial apps. Even Swing doesn't have demos like these.

Congrats, Jeff!

What’s the accessibility story here? I haven’t tried to run these locally but the web translation is completely broken given that it’s a plain canvas that doesn’t try to implement an accessibility tree.

If it doesn’t have that at a minimum then it’s basically a non-starter for business use.

JetBrains "developed a new UI framework" for their new Editor Fleet: https://github.com/JetBrains/compose-jb

I've put a part of the sentence in quotes because actually they've written a new desktop backend based on skia for the already existing Android Compose UI API.

Isn't that what JavaFX was supposed to be?
The problem with all these desktop UI toolkits is they have a look and feel all of their own (IMHO). You can make buttons look like Windows buttons on Windows and OSX buttons on OSX but that's only superficially cross-platform.

Different OSs have different norms, expectations and design languages.

What I'd like to see is something that abstracts as much as it can but still allows you to make something look like a native app on that platform. That would mean you'd need to do some programming for each platform but honestly I don't think there's a good way around that.

The solution isn't Electron. Way too heavyweight. Wayy too resource intensive. Way too risky by having a huge attack surface.

An additiojnal problem with Java is bundling such an app. Requiring a JRE on a target platfrom is (IMHO) a big problem. They're far from universal now. Something that compiles to a static binary. There have been efforts to create self-contained standalone packaging for Java applications. My understanding (which may be incorrect) is that all of these solutions are still somewhat suboptimal.

There is jpackage in the JDK, which can build native packages for Window, macOS, and Linux. There is GraalVM which can create native binaries.
If I had a do-over on Java, I'd get them to make separate interface toolkits for each major platform. Ones that use the native widgets and follow the native conventions. Design them to feel as similar to program as possible, within that limitation. Share stuff that can be shared, but don't force it if it's not as similar as it looks.

Then after that maybe add a cross-platform toolkit that doesn't try to look or feel local, but treat that as a peer with the other UI kits, not a replacement.

> You can make buttons look like Windows buttons on Windows and OSX buttons on OSX but that's only superficially cross-platform.

Sorry, but the problems you are talking about are first-world problems imho. If the button looks like a button, and clicks like a button, what is the problem really?

Yeah, people complain about UI not looking "native", but other than UI experts, does anyone care? Do the end users care?
that's not what they were arguing tho: "You can make buttons look like Windows buttons on Windows and OSX buttons on OSX but that's only superficially cross-platform."

platform design choices are much more than the look of a button. it's choice and arrangement of ui elements, navigation systems, metaphors, ...

if you just see it as "button on windows" vs. "button on macos" it's not that obvious, but think about how you'd design an email client on windows vs. command line vs. mobile phone vs. smart watch.

a simple "button" might be roughly the same on every platform, but the overall design would be quite different.

the problem used to be very visible in early app development: you get android apps that try to imitate ios. the navigation is wrong, the inputs are wrong, the ui language is inconsistent.

it happened all the time when almost all of the graphic designers (which were thrust into the roles of UI designers) were on mac and usually ios but got the task of "designing an app", which meant _one_ design for both ios and android. as an android developer i had to fight the OS, the framework and pretty much everything else to make the designers vision work, which resulted in buggy apps that felt unintuitive to use.

The Web has had buttons that are inconsistent with the native OS for ages, yet users never really complained.

E.g. visit https://twitter.com/ and select Sign-up. I don't know what OS you are on, but the sign-up box probably doesn't look native. Users accept this. So what is the problem, really?

The problem is that any GUI for a not-completely-trivial application is going to consist of much more than a single isolated button and the way that a GUI is expected to behave and be structured is not the same across all platforms so no matter how carefully you mimic the appearance of the buttons, an app that behaves the same onall platforms cannot behave like a native app on all platforms.
Here's a novel approach: Build native applications / user interfaces. Time gained from using cross-platform libraries is negated by all the issues it creates.

It's better to have one developer per platform, than two (or more!) working on a cross-platform application. And you get true native applications; think of things like accessibility options, which are often overlooked in cross-platform toolkits, or performance.

Could not agree more. Users don't need to be "fooled" by an uncanny-valley, years-out-of-date looking simulacrum of native UI, because they're getting the real deal. Accessibility is so overlooked, while some native UI toolkits provide at least a passable default accessibility implementation.
> The problem with all these desktop UI toolkits is they have a look and feel all of their own (IMHO). You can make buttons look like Windows buttons on Windows and OSX buttons on OSX but that's only superficially cross-platform.

SWT (the UI library which drives Eclipse) would give you that on Windows, OSX and Linux. But it's not exactly light-weight...

SWT still doesn't really feel native though. The toolbars, in particular, look like they belong in Office XP.
> The problem with all these desktop UI toolkits is they have a look and feel all of their own (IMHO). You can make buttons look like Windows buttons on Windows and OSX buttons on OSX but that's only superficially cross-platform.

Exactly this -- every cross platform GUI toolkit ends up falling into an uncanny valley where it looks sort of native but subtle things are just off.

This is, I think, a key part of Electron's popularity. Apps made with Electron are so very obviously non-native that they avoid this uncanny valley effect.

Also for desktop apps, Windows is such an inconsistent mess that who knows what's native anymore, and that is the largest platform from a visual point of view, while at least electron doesn't get in your way from an integration and accessibility point of view
I'll take the opposite side of this having been doing cross-platform dev for a really long time: you will never successfully achieve a cross-platform GUI platform that is so successful at emulating the native platform that users can't tell the difference.

You can try pursuing it, but it is a field littered with the dead project before you that have tried the same thing. Xamarin, Flutter, Qt, React Native, the list goes on. Some of these projects are mostly-dead, others are heavily used but no user is actually fooled.

I would propose something different: for Java to develop their own design language, which has "good enough" native platform integration but otherwise doesn't try to pretend. Cross-platform platform users generally belong into two camps:

- Ok with something that appears visibly different from true native apps, but the cost savings are worth it and the users don't care so much about native-feeling-ness.

- Under the expectation that their cross-platform app will be so good that it is totally indistinguishable from a true platform-native app.

My contention is that Java (and other xplat projects) should focus on the first group; the second group is not worth serving because it has always failed, and will always fail.

The problem with the state of Java GUI development isn't so much that it fails to emulate the native platform GUI sufficiently, it's that it's ugly and janky. Improving it should be the goal.

> for Java to develop their own design language

JavaFX is not that?

There was swing before that as well!
AWT before Swing, too, and it worked really well back when there were green threads (comparable it seems to the return of userspace threads in Project Loom?).
I’m surprised this is still a complaint, for two reasons. First, many major apps don’t bother having a native look and instead have their own skins. Second, Windows is such a mess that it no longer has an obvious standard look and feel anymore. This has been shown here recently screenshots. Microsoft’s own products, when not using custom skins, are using any of several “native” toolkits with their own aesthetics. None of them are particularly interesting so if it isn’t for consistency, there isn’t a strong reason to imitate any of them.
Yeah Windows has really shot the pooch this last decade.

It used to be so consistent and poweruser friendly.

Windows 11 has just broken a lot of the poweruser keyboard shortcuts for doing things, on top of all their ads, nagware, telemetry/stalking and various antifeatures, it's like they are begging power users to go to Linux.

> What I'd like to see is something that abstracts as much as it can but still allows you to make something look like a native app on that platform.

Yes, I’ve long thought this as well.

I think it’ll take an entirely different approach than cross platform UI libraries typically take — rather than implementing widgets itself, it would have the developer provide a somewhat loose “UI spec” document that then gets compiled into a UI befitting each target platform. Not only widget appearances and behaviors would vary between platforms, but also window layouts. The only exception to the rule of not implementing widgets itself would be where one platform lacks a widget to avoid least common denominator problems (for example, WinUI and GTK have nothing resembling Cocoa’s miller column NSBrowser control, so those platforms would get an implementation of that view built from other native controls).

It wouldn’t fit every use case since it wouldn’t provide down-to-the-pixel control but it would work for a lot of software.

Jeff, how did you get them to run in the browser on a single click? I would've thought the JRE needed permission or something? It's been a while since I've run an applet. Is this sandboxed somehow?
SnapKit is a huge framework with lots of functionality. One key part for the browser integration module (SnapTea) is TeaVM https://github.com/konsoletyper/teavm

TeaVM converts Java code to run in the browser. It provides the ability to call JS functions to access browser features like canvas and XHR. However, unless you want to be coding like Vanilla JS, you'll want a framework on top. SnapKit provides that.

Not an applet at all! Apps are easily compiled to JS, including needed runtime, so it’s running native. And only 1MB compressed.