Ask HN: How to do cross platform GUI?

207 points by anang ↗ HN
In essentially every discussion about desktop applications there are a lot of comments about how not to build desktop apps, but very little sharing of resources showing how to do it right.

I’ve seen people defend electron, talk about core logic in a cross platform language and native gui code and any number of other options.

As a middle of the road developer I think it’s difficult to find any consensus (besides electron being both simple and hated).

What resources are there for building quality, functional cross platform desktop application?

397 comments

[ 3.4 ms ] story [ 253 ms ] thread
You're using it right now...

If you're careful, you could build something which works on every desktop starting with mid-1990s.

For newer platforms, if you want it to be a "true desktop app", you could bundle the HTTP server. Whatever your platform, there are many options.

Interestingly enough I’m actually posting from an iOS app :)

I am talking about a true desktop app, not a web app.

Are desktop apps dead?

(comment deleted)
No they aren't. And they'll never be, unless a new operating system will be used by everybody. In current situation desktop apps will solve problems that are impossible to solve by web apps (access to hardware being the main one, performance is the next)
Just be careful not to end up with a buggy and laggy mess like for example the desktop MS Teams...
It all depends on the nature of your application. A video editor and a command line utility are so different!

Sounds like you already know the big players so I won't repeat them. Instead, here are some off-kilter ideas:

1. Casual use, general interest, notification-requiring, simple single-file data requirements, tolerant of desktop / mobile split sessions? Try making a chat bot for Telegram, FB, Discord, Slack..

2. Dynamic, visualization-focused UI with simple options that need to be tweaked interactively? Try Imgui[0] or Godot[1]

3. Scientific or data-centric stuff pulling in data from here and there, but meant for interactive exploration? Try Wolfram / Mathematica or an IPython notebook / GoogleColab

[0] https://github.com/ocornut/imgui/wiki/Software-using-dear-im...

[1] https://medium.com/swlh/what-makes-godot-engine-great-for-ad...

You’re right, I definitely could have been more specific. Something along the lines of an office app.

Cool recommendations, thanks!

You should definitely try Godot as tlack recommended.
Build a web site
I’m assuming you mean a web application, however I am looking specifically for resources regarding desktop app development, I’m a pretty confident web dev, so that as an option is pretty clear to me.
qt and wxwidgets are cross platform.
You trade one set of problems (build native app) with another one (browser compatibility). There is no perfect solution when it comes to cross-platform.
Browser compat is barely an issue today. Modern web development tools and more standardization mean you just have to test your code on a few browsers, but 99% of modern JS will run the same on Chrome, Edge, Firefox and Safari.
Have you considered Qt?

As a Mac user I prefer native applications if available. But still, I would consider a well-written Qt application.

For example, qBittorrent is quite alright.

https://en.m.wikipedia.org/wiki/Qt_(software)

https://www.qbittorrent.org/

Are there any canonical resources for learning qt with common language bindings? I know pyqt exists, but there’s a lot of info out there and it’s hard to know what’s good and what’s not. I’ve also found that generally any guides are either kitchen sink level or not much more than hello world.

Where should I look? I’m willing to put in the work!

Beware of there may be Qt licensing issues.
Not really. It's not 1997.

Qt is LGPL. PySide is LGPL. PyQt is "GPL but allows you to link from popular open source licenses".

PyQt is "GPL but allows you to link from popular open source licenses" what is this supposed to mean?
Ah, I see I'm not quite right there. PyQt _used_ to include a file listing the usual open source licenses (MIT, BSD, Apache, Python and so on) as ok to use with their GPL code base, but they since removed that, because in the meantime it has become clearer that the GPL is already giving people that freedom.

https://riverbankcomputing.com/pipermail/pyqt/2014-February/...

Your statement sounds like GPL is giving a "freedom", so like you could use GPL code in an MIT licensed project (sorry if I misinterpreted your statement); this is not true, see https://www.tawesoft.co.uk/kb/article/mit-license-faq "Can I use GPL-licensed code in my MIT-licensed project? No. The project as a whole must conform to the terms of the GPL license and must be distributed under the terms of that license. Therefore such a project as a whole must be distributed as GPL, but can still contain MIT-licensed software."

So it is more like MIT licensed projects give you the freedom to use in a GPL project.

The keyword here is "linking exception". It is a hack to sidestep the licensing problems caused by dynamic linking. e.g. If I encase gcc in java, and release gcc.class under GPL3+, but use it extensively in a separate proprietary java program, does that infringe on the terms of the GPL? Does providing copies of the two together, with a single installer make a difference?

https://en.wikipedia.org/wiki/GPL_linking_exception

Someone else linked a beginner type PyQt tutorial, but just FYI the PyQt API is pretty much exactly the same as the C++ API, down to capitalization. I only use PyQt but still use to the official Qt documentation which is for C++. The only issue can be finding which module a class needs to be imported from in PyQt, which usually can be resolved with Google and then later by looking at old code and copying the few lines of import statements you build up.
PySide2 is the offical Qt Python bindings, and so the Qt website has reference docs and examples for it. PyQt is a separate project by Riverbank Computing.
Are there any modern applications / examples built with Qt? This is the screenshot from the Wikipedia article:

https://upload.wikimedia.org/wikipedia/commons/e/e8/Qt_Creat...

I always see Qt mentioned, so I'm definitely not trying to discredit it. I just never seem to see common examples with it compared to something written in Electron.

Check out Ripcord - https://cancel.fm/ripcord/. It's a third-party Slack & Discord client written in Qt.

Now, don't let the screenshots color your impressions as to what kinds of UI designs are possible under Qt: Ripcord's UI is bare-bones on purpose; it's a selling feature. I bring up this application because it lets you do a more apples-to-apples comparison: IM clients these days are a poster child of an Electron app that uses orders of magnitude more resources than they should for the functionality provided. Ripcord lets you compare the experience and performance with a native app, implementing the same features but without overhead and gratuitous UI shine.

(And personally, I do use it for Slack/Discord instead of official clients.)

Maya, Krita, Octave, OBS, Scribus, Virtualbox, Wireshark. These all have fairly modern Qt GUIs and you can find screenshots around easily enough.

The comparison to Electron is somewhat flawed though. I mean, the GUI in an Electron application owes much more to whatever library they choose than to the fact that it runs inside Electron. Electron provides no particular GUI elements to the developer.

Besides, QtWebEngine allows you to embed chromium into a QT app which means you can effectively get a similar stack as electron but also have the option to use desktop native widgets
I believe many modern car digital dashboards are written in Qt too
Qt embedded is actually pretty nifty. I converted an old GTK "bare metal" interface UI over to Qt once while keeping the "business" logic basically the same other than a couple of tweaks, it went pretty well. The app was pretty well partitioned between backend logic and GUI logic so it wasn't a bad experience at all. All in C++
How did you do licensing? That’s the killer for me on bare-metal.
I wasn't in on that, we had licensing, and I'm sure it was paid for. It was a medical devices company so they had pretty deep pockets.
I'm very happy with the VNote UI, which uses Qt. It's an open source markdown note-taking app. Check out the dark themes.
>I just never seem to see common examples with it compared to something written in Electron.

Autodesk Fusion 360 uses Qt[1]. (It's 3D CAD modeling software like Solidworks/Inventor). Some screenshots of its UI : https://www.google.com/search?q=%22autodesk+fusion+360%22+ui...

CAD/CAM modeling software is resource intensive and users always complain about slow performance when manipulating big files so writing that type of app in Electron/Chrome/Javascript browser engine would be worse than native C++/Qt.

That said, another competitor Onshape is browser-based and yes, people do complain about its performance.

Some other well-known desktops using Qt are Autodesk Maya and Wolfram Mathematica.[2]

[1] https://forums.autodesk.com/t5/fusion-360-api-and-scripts/wh...

[2] https://en.wikipedia.org/wiki/Category:Software_that_uses_Qt

(comment deleted)
Racket has a cross platform GUI library.

I've seen some tutorial some time ago, where someone used libwebkit from Rust, but I could not find it again recently, so the point is: There could be libraries allowing you to talk to a rendering engine and this could be a more mInimalistic approach than Electron.

To add to this, OP, there is an interesting blog with many examples of graphics development in Racket:

https://alex-hhh.github.io/

I have written a couple GUI applications in Racket; maybe they can serve as motivation to discover Racket's GUI capabilities:

https://github.com/evdubs/chart-simulator

https://github.com/evdubs/renegade-way

There are limitations to Racket's GUI toolkit compared to writing a native Qt/GTK/WPF/Cocoa application. You may find it easy to express simple/not-so-complex interfaces and then find it much more difficult to do other things. There's also the fact that Racket's real threads story isn't so great.

If I needed to write a cross-platform GUI application for the masses, I'd probably pick JavaFX over Racket, but Racket has been very impressive if your initial impression is to not expect much.

Racket and LispWorks ($).

If you want a RAD IDE I recommend you to take a look at Lazarus and Xojo ($).

You can try them all and think for yourself. Xojo and LispWorks in particular come with plenty of example apps.

Thanks for the responses! I’m sort of aware of specific products/projects for cross platform desktop app development, and it’s fairly easy to just google and get a lot of the same answers here.

What I’m more looking for are specific resources on how to do it. Like say I choose qt, what then? How do I go from an idea to a cross platform app with a reasonable build pipeline and a clear method for installation?

I don't have direct experience but I know that Codelite and Code::Blocks IDE's use qt and both run on Windows, Linux, and MacOS. You could look at how they do it. Both projects eat their own dogfood, so you can with a little work build and install them yourself. And I 99% certain codelite has a wizard that can create a basic qt or wxwidgets project.

Also see Qt Creator.

Both Codelite and Code::Blocks are written using wxWidgets.
It also depends on your ecosystem of choice. If you know Java then a single maven command will build you a full JavaFX application. If you're more comfortable with web, a single npm command will build an Electron app.
Take a look at Uno

https://platform.uno/

It basically lets you compile WinUI (Windows 10, C#, XAML) apps to run natively on all platforms (Windows, MacOS, Linux, Web, iOS, Android).

Disclaimer: I was part of that project for 3 years.

Feels slow in the browser on my iPhone X
There's Tk (https://tkdocs.com) with bindings to several languages. The simplest and the original one being TCL. What a great language to program in!

Although I've not yet tried it myself, there's AndroWish (https://www.androwish.org/home/home). Deploy your TCL/Tk code on Android with minimal changes.

I used the Tk ruby bindings several years ago and it was easy and looked decent.
Google's flutter https://flutter.io/ is the best at the moment - even if I dislike dartlang, I have to admit the product is amazing.
Note: OP is looking for solutions for the desktop, and the Flutter site[0] warns that desktop support is in an alpha state, with Windows still under development.

[0]: https://flutter.dev/desktop

The way I see it: if you had infinite time and money then you would build a native app for each platform you care about, and when you choose e.g. Electron instead you're making a tradeoff because of your available resources.

When people criticize Electron, I don't think they're saying "given your capacity, you should have picked a different and better point on the tradeoff curve". I think they're just mad that you had the requirements you had and didn't get to apply more resources than you had access to.

So, at first it sounds like they're making a technical argument against anyone who would choose to use Electron, but I think what they're actually doing is instead expressing some kind of economic disappointment in your situation.

(I would probably use Electron on a small budget, Qt on a medium budget, and native apps on a large budget.)

> So, at first it sounds like they're making a technical argument against anyone who would choose to use Electron, but I think what they're actually doing is instead expressing some kind of economic disappointment in your situation.

This is a fair assessment. Still, this disappoinment is worth expressing as it makes it clear the current situation (lack of high-quality, mature, cross-platform toolkit using native widgets) is frustrating. You shouldn't be choosing between spending a lot of resources doing things right and spending a reasonable amount producing an inneficient monster that drains your users' system resources.

That's the gist of it. However, I feel the assessment often flies in the face of Parkinson's law. Economics of software development are funny - particularly if software is a part of a bigger company, there's enough inefficiency in both software teams and the greater organization, that Electron vs. 3x native shell + shared core could not be a noticeable difference in terms overall resource expenditure.

The particularly annoying part about economics here is the "limited oxygen" nature of software products. If you and I both develop a software tool, but I decide to rush it with Electron while you take it slow with native app per platform, I get to (assuming the tool is a-ok) "suck the oxygen out of the space" by releasing first, and you may lose the motivation/market to create the better tool.

Which is to say, "good today" may be better than "perfect next week", but the big reason why software products suck so badly is that "shitty today" is considered better than "good tomorrow".

> lack of high-quality, mature, cross-platform toolkit using native widgets

AFAIK, this is not correct, as WxWidgets fits the requirements (it's almost 30 years old, cross-platform and native).

I'm curious though, since I haven't extensively developded GUI applications, which are the pratical tradeoffs against a non-native toolkit like Qt.

> WxWidgets … native

I don't buy it, something doesn't add up. The look and feel is somewhat out of place, one can tell with one glance it's not native. https://i.imgur.com/LjDhPOv.png

• The scrollbars are too narrow and have only a down arrow at the bottom instead of a combined up and down arrow.

• The font size is wrong in some places in the hex editor.

• The tab in the tab bar is crooked, not rectangular, and lacks a close button.

• The text has too cramped kerning, most noticable in the word "File".

• The underline for key shortcuts is placed too high.

• The ribbing in the lower-right corner is larger.

• Contrast around the menu bar is too harsh.

• The icon bar does not lock (context menu), and always displays a grabber.

• Menu bar and icon bar do not have a context menu.

• The ribbing on the left-right split bar is different.

• The MDI panel only has a close button but not a detach button. There's a obtrusive gradient in the panel title.

• The progress bar does not have the stripe pattern.

I submit that Wx implements its own non-native widgets.

> I submit that Wx implements its own non-native widgets.

It does for the widgets that have no native equivalent, such as draggable/dockable tabs/panels that you show. You can't say they differ from native ones because there is just no native version, on any platform.

OTOH all the standard UI elements (buttons, checkboxes, text controls, date pickers, ...) are native and not only they look natively, but also behave natively, which is pretty important and different from Qt.

Not the person you responded to, but can you explain why if they're using native widgets, every single example application here [1] looks horribly integrated into the desktop? Is wx just really hard to use and every developer screws it up? Does wx use the native widgets correctly but screw up things like padding and highlights? Is the subset of widgets that are supported on every platform too limited, so everyone is forced to use non-native widgets (which apparently always look bad in wx)?

PoEdit comes the closest to looking genuinely native, but the MacOS implementation is clearly flawed.

[1] https://www.wxwidgets.org/about/screenshots/

There are many screenshots here, I'm not sure which one do you mean. But do keep in mind that some of these screenshots (maybe even most of them) are 10, or 20, years old, so what seems non-native to you today might be just the way things used to look.
I really do mean basically every screenshot. But take ECMerge for example. If you switch back and forth between Linux (GTK?) and Win7, you'll see that for example the toolbar is exactly the same color on each. It doesn't integrate with the Windows environment at all. But surely Windows has a native toolbar widget? And possibly even a native icon theme that you could use instead of the GTK icons. And even if not, surely wxWidgets could choose the color of the toolbar based on the desktop theme, and not just fall back to the same default colors?

Or check "Game Develop". The primary interface is a kind of weird rip-off of the MS Office ribbon, but I assume this is a custom widget. There's also a tab interface though, and this doesn't work on either the Windows or GTK versions: it's weird and has a gradient background.

In general, small details like the padding, coloration, and borders drawn around widgets seem to be slightly off on most platforms with just about very wx based GUI I've seen.

ECMerge seems to use standard wxToolBar which is definitely a native control, so I don't know why it has the same background on all the screenshots. Perhaps they've explicitly changed it to make them more similar, I really can't say. But if you create a toolbar out of the box, it will look exactly the same as in any other native application. As for the icons, wx does provide a limited set of stock icons, but this will almost never be enough, so you need to either get high quality icons in the style of each platform you support, which is obviously difficult for an open source/free program, or use the same, typically Linux-style, icons everywhere just because this is what is there, for free.

The rest of the controls (ribbon, tabs) are indeed non-native and there are no native equivalents for them, so there is not much to say here.

Generally speaking, there shouldn't be any problem with the colours unless you change them explicitly, which is a bad idea for the native controls. Not sure what is wrong with the padding and borders.

> OTOH all the standard UI elements (buttons, checkboxes, text controls, date pickers, ...) are native

Well, let's verify that… https://i.imgur.com/uHfjoUs.png No, they're not.

> draggable/dockable tabs/panels […] You can't say they differ from native ones because there is just no native version

That sounds wrong. Why should they not be? Do you have any proof?

> Well, let's verify that… https://i.imgur.com/uHfjoUs.png No, they're not.

Sorry, I don't know what is this supposed to prove, but I can definitely assure you that all the mentioned controls, and many others, are exactly native controls under the 3 first tier platforms (MSW, GTK and macOS).

> Do you have any proof?

Proof of absence of something is hard to make, all I can say is that you can go through MSDN, GTK and Cocoa documentation to convince yourself.

Wxmp3gain is from more than 8 years ago, and (it seems) you're basing your judgment on a screenshot, which is not a very solid ground. Using a modern, live, application would be a good test (keeping in mind, that some widgets may not exist in a given O/S).

Regardless, since you're accusing a very old and widespread project of lying ("it uses the platform's native API rather than emulating the GUI" on their front page, versus "I submit that Wx implements its own non-native widgets."), you should directly ask on an official channel, and have an authoritative answer.

I mentioned look and feel, and testing out the absence of context menus. This should tell you that I am not judging on a screenshot, but from live applications. I made that screenshot yesterday, and the applications depend on 3.0.4 which is from 2018.

> since you're accusing a very old and widespread project of lying

http://enwp.org/Appeal_to_accomplishment Nice fallacy, don't think you can pull cheap tricks like that on HN.

But anyway, let them defend themselves; veritas liberabit vos. FWIW I don't think malicious or intentional lies are involved, although a mighty good explanation is required to square their claim against the evidence that it is plain to see.

It would have been more productive to spend the time to find a technical answer, rather than arguing for the sake of arguing. I did search, and the answer is at the bottom.

Note that one of the posters you've been arguing with ("VZ"; argument here: https://news.ycombinator.com/item?id=24259040), turned out to be the WxWidgets maintainer. According to the comment though, mentioning this constitutes a cheap trick <rolling eyes>.

Regardless, there is a very interesting concept in the explanation: using native widgets through WxWidgets (and possibly, widget toolkits in general) requires following specific guidelines. Failing to do so will make the widgets look bad, even if they're native.

  First of all: The "VZ" who wrote in the thread you linked, is Vadim Zeitlin, the
   core maintainer of wxWidgets. His word is the highest authority in the wxWidget
  s world.
  
  My 2 cents:
  
      are all the widgets provided by WxWidgets native?
  
  No. But if a native implementation of a control exists on a specific platform, i
  t will be used (i can't think of any exceptions right now, but it's possible the
  re are a few).
  
  Most widgets are native on all platforms, e.g. wxButton, wxTextCtrl, etc.
  
  Then there are widgets that are only native on some platforms. E.g. wxDataViewCt
  rl. Is has native implementations on OSX and GTK, but as no such control exists 
  under Windows, a generic implementation is used there.
  
  Then there are widgets that have no native implementations at all, e.g. wxGrid.
  
  In general, wxWidgets just gives you the toolset to develop crossplatform GUIs. 
  That doesn't guarantee it that they'll look good everywhere out of the box. This
   also requires "good" behavior of the developer. E.g. they should not use absolu
  te values of controls sizes and positions, but use wxSizers (the wxWidgets layou
  t system) instead. Lately they must also be prepared for high-dpi screens, good 
  support for that is only available in wxWidgets for a few weeks now.
  
  Also, many open source developers only develop on one platform and hardly ever o
  r never test on other platforms. Often they just don't want to invest more time 
  to make their application look good everywhere.
  
  Regarding https://imgur.com/LjDhPOv
  
  wxHexEditor uses wxAUI, this is not native anywhere. The window with the hexdisp
  lay could be custom drawn, there is no control that does this out of the box. Or
   it might be a wxGrid, hard to say.
  
  wxMP3gain looks fine to me
  
  easyMP3Gain seems to be one of the case where the developer just didn't care to 
  make it look good.
If it wasn’t electron then it’d be some other behemoth FW to fill the void. It’s what we get when computing power is so great. Eventually a bloated, lumbersome, massively layered code base runs functionally OK that it becomes acceptable and universal. As somebody who started writing 6502 assembly and appreciated the elegance (still do), the success of things of bloat like electron is soul crushing.
If I had infinite money I would use something like Xamarin.Native (aka Xamarin.iOS/Xamarin.Android aka Xamarin.Traditional aka Xamarin) to write a 90% shared codebase and develop my own UI dsl with the rest in native code. Codesharing for everything but the UI is a _huge_ maintenance win. The mechanism that Xamarin uses to do its cross platform means that you don't pay much of a performance cost to achieve this, because its mostly just a binding layer to native code (NOTE: not talking about Xamarin.Forms here).
I say the opposite: Build with "mediocre-first" cross platforms (all of them are mediocre) is long term the MORE costly option.

With native UI, eventually the development will stop. With cross-platform, you will, FOREVER, try to catch up.

P.D: i have used more than +12 main languages and as many or more UI toolkits.

The native UIs are running even close to a DECADE without nothing of significance on maintain. The rest? is rewrite, recode or workaround....

That's not the opposite of my point -- you're just rephrasing it.

If I can buy a cheap roof for $2k but have to replace it every year, or an expensive roof for $15k that will last 50 years, then LONG TERM the cheap roof is the more costly option.

But if I only have $2k instead of $15k, I'm not wrong to buy a cheap roof. Yelling at me about the long term costs of the cheap roof is missing the point. You're just saying that you're disappointed by my lack of $15k.

Thats a fair point, just thinking that most think are in the second scenario (by pressures that also make cut testing, planning, etc) but really are in the first one.

This happens a lot, because some of the "advice" in this industry is for "startups that if not ship something like now will die", when the majority of the work is not that disposable...

Flutter looks nice, but it's dart.

In a sane world we would already have webviews on all platforms and the problem mostly solved for client applications. But there's a lot of forces at work that want to artificially suppress web UI. Chromium doesn't have webview on desktop platforms, but Microsoft's chromium edge does. Apple puts in their special restrictions making up rules for any app that uses wkwebview.

Nobody with the power wants to make webUI universally deployable.

At the end of the day you choose one that you'll actually deploy something with. There's no more right or wrong in UI, it's can you get to the goal of deploying a functional app or not.

In all fairness I think Dart is Flutter's strength, not it's weakness. It is a very well thought out language, unlike javascript(in the spirit of discussing electron).

There is undeniably a problem with flutter however: while it can be used for desktop applications, it's mobile-first, desktop-sec.. well... desktop-kinda-sorta-works...

I don’t mind dart, but typescript and electron have the full weight of Microsoft behind them while dart and flutter remain mostly hobby projects.

We did the business case for cross platform, as we’re a non-tech enterprise organisation with 10.000 employees but few developers. We wanted flutter to win, but react native came out like the sound choice.

> while dart and flutter remain mostly hobby projects.

What makes you think that?

They have spent more than 3-4 years with millions of dollars on it.

You'd be surprised how many top-downloaded apps are made with flutter. Electron and typescrypt may have some potential but they have a horrible genetic desease - javascript. That alone makes flutter a clear winner.
Also I think having a highly integrated toolchain is really important for this. Building something cross-platform with Flutter feels just like a fresh breeze even for web which is a beta target (Desktop being alpha). I would have never gotten the idea to write a web app in Dart, but with Flutter it feels just fine. Like Typescript but from Google.
Speaking of the web, angulardart got a major update a few weeks ago. And on the subject of web-app-on-dart, my personal site is written in dart (and the 'platform', as some people would call it, is open source for that matter if someone wants to use it or contribute).
Dart really isn't that bad. I thought I would hate it, especially going from Kotlin.

I still prefer Kotlin, but there have been very, very few occasions where I've not been able to do what I wanted with Dart.

>In a sane world we would already have webviews on all platforms and the problem mostly solved for client applications

Isn't WebView kind of work around for web browser being overbloated? I mean they made single instance of browser and interfaces for embedding that single instance, but do you really need that for desktop?

You should give JavaFX a shot. It's not considered cool here, but does the job well IMO. I have built desktop apps that work seamlessly between MacOS, Windows and Linux using JavaFX with minimal pain. I was already quite familiar with Java and the Java way of doing things though. That probably helps.
For the people having apprehension around Java’s performance, let me tell you that my 12-inch MacBook with a mobile CPU managed to run IntelliJ IDEA just fine (a heavy Java-based IDE) but significantly struggles with Microsoft Teams (Electron-based chat client).
Yeah. Java's default performance isn't bad, and the floor is quite good (lots of space to optimize if needed). Just avoid bloating it up with enterprise framework when you don't need them.

JavaFX doesn't seem as snappy as native OS GUI frameworks, but I've found it very nice to develop for. It comes with reactive model out of the box, and there are some extra libraries that take it up to 11.

I recently finished a project in JavaFX and am looking to build another application. I've been unsure of whether to continue using Java or use native widgets.

I'm very comfortable with Java, but one of the issues I've had is the size of the resulting binary with the JRE included (it's possible to not include a JRE of course, but it's much easier to have it bundled from a user perspective). You can use jlink to reduce the size of the bundled JRE so that it only includes relevant modules, but does it actually reduce the binary size by a significant amount?

Also, JavaFX doesn't seem to have backing from larger organizations like Electron does. Are there any well-known apps created with JavaFX. I know IntelliJ was created with Java but using Swing if I recall correctly.

I ship a JavaFX app build with jlink. It includes many JDK modules beyond JavaFX, like `javafx.swing` and `jdk.unsupported` in order to access some features that unfortunately are not available in the standard modules, but even then the download size (zipped) is around 35MB, more like 65MB unzipped.

I would say that's pretty acceptable for a real app.

(comment deleted)
Maybe you interested combine QT with react?

- https://docs.nodegui.org/

- https://react.nodegui.org/

Indeed. I'm currently experimenting with NodeGUI and React Native as a means to write React components shared by web, Android, iOS, Windows, Mac, Linux. Early days, but it broadly seems to work. I can even swap in Preact for web, RN for mobile, and NodeGUI for desktop builds with enough webpack config fiddling.
There's React Native for Windows and Mac now. Still pretty early on, but worth a shot especially if you're also targeting mobile platforms (you can share a lot of logic and some UI).
Left of field, but game engines have figured out translating a single set of UI APIs to multiple graphics backends already.

Alternatively you could use a compatibility version of OpenGL, like 3.3 which will run on any desktop OS, then use a windowing lib like glfw and UI framework like Dear ImGui which is graphics API agnostic. I use this particular combination all the time and it never lets me down. Sokol is another options which is a very thin layer over many graphics APIs.

I believe this is how flutter (and by extension, chrome) works as well
> Left of field, but game engines have figured out translating a single set of UI APIs to multiple graphics backends already.

I can't speak for Unity, but as far as Godot is concerned, the workflow for certain things like layout and text styling leave a lot to be desired if you're not making games.

Really, that just means waiting until more suitable plugins are available.

Avalonia is a cross platform port of XAML, that is ready for app development. I’m waiting for it to move to .Net 5 though.

There’s also FuncUI, an elm-like layer over Avalonia written in F#.

We develop on Avalonia, it provides very limited control set and functionality, and 3rd party libraries/controls do not exist yet. Cross-platform framework requires some time to become mature and create ecosystem around.
Checkout https://GitHub.com/qmlnet/qmlnet

It leverages the entire Qt system with the power of .NET. We use it on embedded medical devices.

And how's it on production? I remember, we considered it, and rejected because the framework visibly far from release. Maybe, we were wrong.
Cross platform is always going to be a compromise. You will never achieve a fully native feel for each platform and in trying to do so will soak up a huge amount of time.

So I'd start by asking yourself whether you really need your application to be cross platform.

The question is not whether you want your application to be cross platform. After ~10 years of app development I can say that in almost every case I do want to share codebases.

The real question is "where do you draw the line for cross platform code?". In other words, do you want everything to be potentially shared or do you only want the "business logic" to be shared? Unless theres a real constraint on time, I've found the best option to be starting with shared core + native views and migrating the view logic into the shared core over time as you discover the UI patterns.

You can have native feel by using a framework that binds to the native directly. In my opinion Xamarin is the best option currently, but Kotlin Multiplatform is a possibility once they mature.

We’re experimenting with using a rust core library (matrix-rust-sdk) for next gen Matrix clients for code reuse/maintainability/performance/safety, but then doing platform native UI on top for optimal UX (via swiftui, web, android, gtk, etc). It remains to be seem how well this will work :)
Hey, are you absolutely set on GTK for non-linux systems?

It has accessibility problems, excludinga certain group of users, including blind people. I'd urge you to reconsider.

Please file bugs in GTK for the accessibility issues you're having, there is interest in getting those fixed.
An underused option is to include a local HTTP server in your native app and open it in the user's default browser. This avoids some of the resource consumption and security issues that make Electron bad, but still lets you integrate native code with a web UI.

I wrote a little framework for this: https://github.com/jdarpinian/web-ui-skeleton

This is how Electron style apps should work, instead of wrapping an entire browser instance around each app to maintain the illusion of it not being at all web based.
They are called PWAs
PWA refers to the client-side app only. They are not related.
How do you figure? You can locally host or package a PWA same as Electron. Chrome at least is closing the gap in capabilities too.
(comment deleted)
No. I want to be able to Ctrl-S and it save the changes I made to the file (for example, but this is the most annoying thing for me) That doesn't work with actual browser.
Yes it does. Just preventDefault() the keyDown event.
And now you start a download and the modified file goes into the User's download folder as file(n).whatever instead of wherever they opened it from.
No, remember that you have a local server running native code. The server can handle writing the file to any path you want.
But if you do that, you also have to handle file opening from the native local server side too (because browser file browser will not tell you actual file path). And of course, that dialog won't be a modal of the browser.

This is getting weird very quickly (not to mention that Ctrl-S in browser windows saving file without confirmation is a UX I wouldn't want to use)

> And of course, that dialog won't be a modal of the browser.

There are several decent options. You could build a modal that displays a view of the file system sourced from the server. Or you could pop a real native file dialog from the server, and I'm betting it's possible to either make it a real modal of the browser window or do a good enough simulation depending on platform. Or in the future you could use the native file system API that is currently in origin trial.

I submit that this is not weirder than most cross-platform UI toolkits that implement their own whacky replacements for the native file dialogs.

Is there a good way of doing SSL with this that doesn’t require hacking self signed certs into the users browser? A lot of newer web APIs are requiring SSL.
You can access those APIs using SSL from the server, which then relays the results to the client.
I believe that Chrome treats all localhost connections as secure now. Not sure about other browsers.
I've worked on some applications like this, and it works pretty well. But be aware that a port on localhost is accessible to any local user - depending on the application you may need to prevent other users accessing it.

Running inside a real browser also limits the keyboard shortcuts you can use, because you don't want to clash with the browser's own shortcuts.

Weirdly, Windows makes it easier to do this securely in that you can do NTLM authentication to authenticate local users (maybe MacOS as well, I believe internally it runs its own Kerberos server for the local machine).
AFAIK you can only do this if you disable the local loopback check that prevents windows auth from passing credentials to local host webservers.
Why did they put that in in the first place? To stop cracking of local passwords?
Can't this concern be easily alleviated by the backend requiring credentials, and sending them along from the frontend? Getting around this as an attacker means already possessing enough rights to not need sniffing the traffic to the backend. Or is there more required?
It can, but getting the credentials to the browser & storing them there isn't entirely simple. If you launch a browser process to a URL containing a token, an unprivileged local attacker can see it in the command line arguments (at least on some platforms) and copy it. That can be mitigated by launching the browser with a file:// URL which uses an HTML meta redirect to give the browser the token.

The obvious way to keep the browser authenticated is a session cookie. But cookies are shared between all ports on a domain, so a local attacker who tricks you into visiting another localhost service in the same browser can steal the cookie. localStorage doesn't have that issue, but it's not so convenient for authenticating requests.

You can capture most keyboard shortcuts in the browser these days, and the native server side can handle registration of global keyboard hooks if your app needs those.
I'm thinking more of the user experience if you take over shortcuts people already use for their browser.
Usually if it's already local, you don't mind localhost connections. If you do, you can negotiate a shared cookie or other auth mechanism. Otherwise, you should at least check the host header to prevent DNS rebinding attacks.
But if you want to interact with local file-system (like open dialog) it start to get complicated.
> security issues that make Electron bad

Exposing a HTTP port with application state is a million times worse for security

The server binds to the loopback interface, so it's not exposed to the network at all. Then as long as you use CSRF protection and an appropriate Content Security Policy it is safe.
I see a lot of people suggesting Qt, is there a reason GTK isn't being suggested at all?

I'm in a position where I'd like to develop a better client for Bitwarden that includes autofill to the point of 1Password, and while I did start with GTK (learning for the first time), seeing no one recommend GTK here (compared to multiple people recommending Qt) isn't filling me with confidence

I found GTK with Python really nice. With a bit of effort you were able to make it look native on all platforms. Clean API, visual Editor, and quite performant. Unfortunately the project suffers a bit from CADT (Google it) and the devs break backwards compatibly all the time. They seem no longer interested in providing compatibility across versions or for platforms other than GNOME unfortunately. With GTK 2, you could write an app with e.g. GTK 2.16 and it would still run with 2.32, but receive all new features from the toolkit. Now you are expected to constantly change your app with every release.
GTK+ 3 was a bit of a nightmare in this regard, but GTK+ 3 is also feature frozen and will be supported for more years to come, so a new application doesn't have as much to worry about here.

The downside would be the desire to port to GTK+ 4 in some amount of time, which might require a large amount of effort depending on the application. On the other hand, if you're starting today you could also start with GTK+ 4...

That's half of my complaint, that the GTK+ devs consider "stable" to mean "frozen". You are supposed to code against the latest completed version (e.g. the final GTK+ 3), which will not receive compatible feature updates, and then if you want to get the new features you have to port your code to the next version.

Whereas under the old model (GTK+ 2.x) it was forwards compatible (if that is the right word) - you code against a stable but actively developed version, and your code will work with no or minimal changes for multiple years, and you will receive the benefits of new versions (historical examples: changes to file open/save dialogs, theming changes, window resize grippers, dragging windows from menubars, ...).

> I'm in a position where I'd like to develop a better client for Bitwarden

Beware that, if you use GTK, you exclude a certain segment of the population who need Accessibility and aren't on Linux. This definitely includes screen reader users, but probably also users of voice recognition, switch control etc. QT works much better here. This is yet another tradeoff to make.

What kind of misinformation are you trying to spread here? GTK+ has accessibility built into the toolkit itself - it's not optional, and it's always on. In fact, GTK+ had it before Qt did - ATK was written back in 2001 to be a part of GTK+, and the screen reader Orca is written to use GTK+ and the platform agnostic AT-SPI layer. It would take a full ten years for Qt to add an implementation here.
The parent post is saying it doesn't plug into the native a11y, which is true. Running the at-spi daemon on windows/mac would work for some things but it is obviously not ideal.
COnsider that a lot of people who are forced to use GTK aren't actually on Linux, and Windows and Mac accessibility is literally nonexistent.
Unless things changed a lot in the last ~three or so years, Non-Linux platforms like Mac and Windows aren't really in the focus of Gtk+. In the past ~five years a large number of cross-plattform Gtk+ applications redeveloped their UIs in "Not-Gtk+" (usually Qt). Wireshark, Subsurface, Openshot and LXDE come to mind, these are all pretty large, UI-centric projects, so replacing the toolkit is a lot of work and wouldn't be something you'd do just for shits and giggles.

If you really, really want your app to use Gtk+ on Linux and be reasonable elsewhere, consider wxWidgets.

I'm not in the discussion above, but I would never recommend GTK for any cross-platform application because it enforced a Gnome-only look and feel that is completely alien on any other environment (even on Linux).