Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Cross-Platform GUI Toolkit Trainwreck (2016) (johnnovak.net)
167 points by aparashk on April 25, 2019 | hide | past | favorite | 170 comments


So many sub-debates hidden in this "cross-platform native GUI":

1) I want to write a GUI code once

2) I want to ship something that works on Windows / Linux / MacOS

2.1) I want to ship something that looks the same on Windows / Linux / MacOS

3) I want to ship a binary that works on Windows, a binary that works on Linux, a binary that works

3.1) I want to ship a small and efficient binary

4) I want to ship something that looks like a Windows app on Windows, a Linux app on Linux, a MacOS app on MacOS, etc...

(By definition, "I want to ship something that looks the same everywhere and looks like an app of my host" is meaningless, right ?)

The "holy grail" seems to be:

5) "I want to write a GUI code once that generates small efficient binaries that looks exactly like an app of the host OS, and if possible looks the same everywhere, and let me go back to writing my business logic rather than agonize over drawing a button."

It's seems from the debate that nothing obvious fulfills 4 and 5.

Then it comes to which requirement you're ready to drop.

If you're ready to drop requirement 2) , I suspect you're doing MacOS specific, go for it ;)

If you're ready to drop requirement 1) , I suspect your managers / salespersons disagree.

I suspect your manager / salespersons do not care about requirement 3.1), but it's debatable. Use Qt/Electron, and ship something.

I suspect your manager / salespersons do not care about requirement 4), and I suspect they're esthetics, which can not be defended.

I gave up waiting for someone to make 5, and don't have the resources / skill / time to do it myself. And maybe we should stop caring and watch the sky instead.

I hope someone is able to get to 1 + 2.1 + 3.1 someday.

I'll use that.


> 1) I want to write a GUI code once

> 2.1) I want to ship something that looks the same on Windows / Linux / MacOS

> 3.1) I want to ship a small and efficient binary

well, with Qt I write my code once, which looks the same on windows / linux / osx / $nicheos and the result is fairly performant - I've got tables with tens of thousands of elements which update at rates greater than 100hz and the UI does not bat an eye. I'm not even using the GPU-based scene graph (QtQuick) but instead uses the CPU-based raster engine. Here's the software I'm developing : https://github.com/OSSIA/score/

So what is missing ? For what it is, the binary is relatively small (and I also link against LLVM and a few other large libraries, and am not even doing global static linking + LTO...).


Out of curiousity, how big is your binary ? Seems like everyone does not have the same definition of "small", hence the brackets ;)

But sure, qt seems to hit 1,2,3 , although 3.1 will fuel flamme wars that we dont realky care about as long as you can ship code. Good for you !


I've got tables of millions of rows and can also confirm Qt just performs!


Great list and summary! So often these concerns get conflated.

We're working on a framework that address 1, 2, 2.1, 3, and 3.1 - Revery [0] - a React-like framework that compiles to native code, built with ReasonML [1]. I believe that the React pure-functional model of UI-as-a-function-of-state is such a powerful paradigm, and not leveraged on native today - ReasonML is a perfect fit for that.

Bullet point 4 is a non-goal for Revery, but our sister project, Brisk [2] is built on platform widgets.

I'd personally also add a couple of dev experience bullet points or ideas to the "holy grail":

6) Fast / instant compilation time

7) Hot-reload (see changes to the app instantly)

We're not there yet, but we hope we could also get to the point of including 6/7 - essentially bringing some of the great aspects of React/Redux to desktop application development, with native code.

- [0] Revery: https://github.com/revery-ui/revery

- [1] ReasonML: https://reasonml.github.io/

- [2] Brisk: https://github.com/briskml/brisk


I'm working on something that might do #4 and #5:

https://vlang.io/#ui

An example of a small GUI app:

https://github.com/vlang/v/tree/master/examples/users_gui

The app is about 100 KB on all platforms with zero dependencies and uses native toolkits (WinAPI, Cocoa).


V looks pretty slick, though your 'comparison' to nim (https://vlang.io/compare#nim) is incomplete.

i.e. you don't actually write comparable code. Instead, you just lambast how slow the compiler is.


The comparison is very biased. Various claims are not true or provided without context.


If you say what exactly is wrong, I'll update the page.


As everyone on HN, looking forward to being able to use the vlang compiler (sorry, you're going to have a hard time making anyone use V as the language name, for sad search engine reasons ;)


I absolutely love this project.


webview kind of satisfies 1 + 2.1 + 3.1 today.

Same idea as Electron but it wraps the OS webview instead of Chromium (Cocoa/Webkit, gtk-webkit2, MSHTML, and soon EdgeHTML). The minimal test app is 255kb in size, the static lib is just 48kb (MacOS).

https://github.com/zserge/webview

And I get, "but Safari/IE/whatever are still different platforms!" I'd argue that the edge cases between browser rendering of HTML + CSS + JS is much better to deal with than the architectural and language differences between the native GUI APIs on each platform. As long as you're not pulling in an obscene amount of JS dependencies, webview is very sane.


> 2.1) I want to ship something that looks the same on Windows / Linux / MacOS

Why?

I want my macOS apps to use Mac-native UI elements, and Windows apps to use Windows-native UI elements. (There is no one native Linux UI, so we can leave that one aside...)


I want the complete opposite. I use the three systems almost daily, and I freaking hate to have to context-switch to the platform's look-and-feel. Thankfully KDE apps work mostly everywhere nowadays.

Most of the users of the FOSS software I'm developing also switch platforms depending on the project they're in, but they want the software to be the same everywhere for instance.


Are differently-styled UI elements really a mental burden? I'm not advocating for wholly different UI's on each platform—just that if your application uses checkboxes, and I'm on a Mac, I should see Mac checkboxes.


It's probably more the behavior things. Keyboard shortcuts, focus behaviors, menu placement, file dialogs, etc. Settings panels in MacOs should take effect immediately, while in windows you have to click ok/apply... inconsistencies like this can lead to frustration.


But not doing this brings about an even worse kind of context switching—between apps on the same platform.

As annoying as it is to switch form cmd+C to ctrl+C when I go from Mac to Windows, it's even worse when a Mac app uses ctrl+C.


this, and also the need to write three (or four if you want to do separate stuff for KDE & GNOME) times the amount of documentation to accomodate for the different "default" behaviours.


Because someone gave the brand team authority and they can't have their brand take second place to Microsoft's or Apple's.

Branding teams are in my experience very picky about lots of stuff. For example, my employer's brand design team recently released a rule that when our logo is included alongside others logos in a list of companies involved in a partnership, it may not be included in a vertical list, only a horizontal list.

Using the standard background colour for the platform on your app when it's not one of the brand design team approved colours? Also out.

etc. etc.


I maybe biased after doing web work for toi long, but "hey, the site does not look the same in safari than on edge" has occupied a lot of my time.

It's a common concern to avoid confusing users who switch OS often (eg when demoing on someone else's machine.)

The fact that it contradicts the other requirement ("but it does not look like the other apps") is lost on no one.


This is less fashionable now in the era of Electron apps - users are starting to expect apps that look _the same_ everywhere.

See VSCode, Discord, Spotify...

It's easier to get a single code-base that 'just works' across platforms if you have an abstraction that is truly cross-platform. One of the major value propositions of developing with Electron is this ability to develop cross-platform 'with confidence' - I can build an app on Windows and be 99% sure it's going to look function the same on OSX / Linux.

> I want my macOS apps to use Mac-native UI elements, and Windows apps to use Windows-native UI elements

That's a fine goal but it means you end up needing more platform-specific code. It's a trade-off, and there isn't a one-size-fits-all solution.


But do people expect the apps to look the same? I think people want them to behave the same with a few visual features kept intact.

To take Discord as an example, I don't know that people actually can't live without the UI slavishly copied for every platform; I think people rather want light and dark themes on all platforms, message formatting to look basically the same, and for everything to be found in roughly the same place.

This idea that users expect apps to look the same is, I feel sure, something someone said and everybody has gone along with. In my experience, people want things to behave consistently — so if Discord had a native Windows client and a native macOS client, people would be more interested in whether or not they could still find the little microphone and headphone buttons at the lower-left of the screen, sod if the icons and colours are identical.


I don't really have an attachment to any of the three platforms; I use all three. Moving between different windowing environments and UI designs is a huge context switch and provides no value to me (it's just eye candy).


The only valid case for this (IMO) is really expensive professional apps. Where someone is going to spend years getting really, really good at using a piece of software, and you want them to be able to just use it the same way regardless of platform. And you especially don't want people to have to re-learn how to use your really complicated software if the host OS changes how scroll bars appear or the position of window chrome.

But I suspect lots of software companies would think that describes them, when in reality there's probably fewer than 10 products that meet that bar.


Hmmm... node+electron solved MacOS/Linux/Windows, but the snag was I implemented everything in JavaScript, probably not doable for most folks, but for the past 4 years support has been very easy and I have encountered zero platform issues (except for icons on MacOS). I guess I'm the one anecdote that succeeded.


> I suspect they're esthetics

Totally unrelated to your point, but I'm curious as to what this word means in this context.


I mean I imagine a large part of the "look and feel" specificities in mac apps are questions of tastes and beauty and conventions rather than core functionality. And this matter, don't get me wrong, just not always at the same level as being able to use the app without waiting x months of more development. Sorry if the term was inadequate or sounded pejorative.


ReactXP (https://microsoft.github.io/reactxp/) targets mobile and desktop platforms using the OS's native UI.

Windows support is implemented via https://github.com/Microsoft/react-native-windows and targets W10, Xbox, and Windows Mixed Reality.

MacOS support is experimental, but mostly working. Linux currently needs an Electron wrapper. Theoretically you could port one of the react-native-desktop projects to use GTK or Qt.

Then of course you have native iOS and Android components with Facebook's ReactNative and web support via React.

ReactXP wraps all of these projects allowing you to write React components and TypeScript code that is shared among every platform. It's the same workflow as Electron, even less so, with native UI.


This is a particularly good summary, thanks for that. At the end of the day, the only way for 5 to happen, is for a development project to architect the requirements and complexities way before even starting to code.


Aren't 2.1 and 5 pretty impossible to have at the same time? How can you look like Windows on Windows, Linux on Linux, and Mac on Mac, all while looking the same everywhere?


The 5 says "look the same if possible", which is fuzzy, contradictory, and exactly what people want, of course ;)


Don't forget the implicit:

6) Using my preferred programming language.


soon flutter should be able to achieve your last requirement


From https://flutter.dev/ , it seems flutter mostly targets Mobile applications, is that the case ? Is there a "desktop app" port ?


They are working on it, you can check the wiki/Desktop-shells link below for progress.

https://github.com/flutter/flutter/wiki/Desktop-shells

they say -

"Work is ongoing to extend Flutter to support desktop as a target environment, allowing developers to create macOS, Windows, and Linux applications with Flutter"


To date, the best solution to this problem that I have seen is to write all your core code in a shared library using something like C++, and then hooking it up to a thin layer of completely native, platform-specific code for the UI. It’s fast, lightweight, looks good, and requires minimal extra code if you do it right.


It is still a lot of work if you need advanced things then the basic widgets. Thinks where usually you need to extend existing widgets like you want an advanced datagrid/table with sortable/dragable columns, with custom item renders for some columns (like a chart widget for the Trends column).

In this advanced cases you will need to create custom widgets for each platform, hope that all platform have the advanced datagrid widget(if not you will have to create it) etc.

For simple apps your solution works, and you could also make a CLI app too.


Exactly. There's GUIs and there's GUIs.

When I've looked at libraries, I always consider how you'd implement the Visual Studio interface with them.


Right. Things like trees, multiple windows, theming, advanced components (with deep composition), collection views, etc. These are the real use cases for a library like this, but no such thing exists apart from Gtk and friends.


Exactly, and I see people that will say you can do X with html/css and js but when you look at that example is full of bugs(for corner cases), missing features(like missing essential events), are not efficient etc.

If you look at a mature GUI library advanced widget you will see how many events and thing supports and how many bugs were reported because there are many corner cases that need handling.

I worked a lot with Flex4 I loved the fact that the widgets were optimized, you could have a list or tables with 1 million items and it would not affect performance. In Web I see the pattern where you use a lot of pages, you show like 12 results and you have the user hit Next and Next when you could have fitter a lot or even all the results on a large page, especially if is all text


Shameless plug: https://github.com/AshampooSystems/boden We are working on providing exactly that thin native wrapper in modern C++ without much bloat.


I can make a GUI in Qt and it will work on android, but I developed a simple time and there was a huge problem. When device goes to sleep it don't runs any code in background and I couldn't play or do anything on timeout. Does your framework solves any problem?


Are you associated with https://www.ashampoo.com ?


Yes we are a subsidiary of https://www.ashampoo.com


Do you guys plan on supporting desktop apps or are you sticking with mobile?


For the first release we are sticking with Mobile, but Desktop is "next on the list". ( And there is rudimentary macOS support right now )


MVP (Model View Presenter) is one approach to decouple the UI from the interaction logic to achieve that goal. Only the view implementation has to be platform specific. The viewmodel is also shared among platforms.


Is that the pattern React implements? I've seen it being used for mobile and VR for example, but IIRC you need to use different components for those targets. I do recall someone replacing the renderer output from HTML to err, text or XML I believe.


I think this is the best option but for most it's still a lot of work. I spend far more time on the UI code of my applications than I do on the model or domain specific parts.


Wonder how the author didn't come across Qt or wxWidgets in his research?


I have the same question. There are many things that are problematic about Qt (personally, I loathe anything that feels the need to interject itself in the middle of the build process) but to completely ignore Qt without explanation - and subsequently post detailed experiences with libraries I've never even heard of - led me to believe the author exists in some uninteresting-to-me parallel plane of existence.


There was plenty of explanation for me when I first encountered this article (in the context of trying to solve the same problem):

> what cross-platform libraries are available for Nim!

Things might have changed over the past couple years, but, at least at the time, there weren't any (usable) Nim bindings for either.


Fair enough, but I think that the onus of proof is on the weird-language-user here. That is, a discussion of how cross-platform GUI toolkits are a 'trainwreck' takes on a different vibe if you're insisting on using Nim or Left-Handed Pure Phenomenological Haskell or the like.


I think you're maybe over-interpreting the article.

There is no (grammatical) article in its title. You seem to be assuming the article is implicitly "the", which would imply that it's intended for a more-or-less universal audience. It could just as easily be "a", which would then mean that it's more of a personal rant about the author's specific situation. I'd argue that the leading two sentences in the italicized portion of the article imply that it's the latter.

For the sake of throwing my own $0.02 in, I also have a historical habit of blithely ignoring wxWidgets and QT for my hobby projects. Their being written in C++ bit is a bit of a deal-breaker for me. The quagmire of interacting with C++ code from a language that isn't itself C++ in a cross-platform way results in me shaving my fill of yaks during working hours; I have little taste for doing even more of it during time that's supposed to be reserved for fun.


Yes, I guess so. I suppose I'm startled that someone would write such an elaborate article about such a remarkably specific situation without some intent to make a general statement, but whatever floats his boat I guess. You're definitely right that interacting with C++ outside of C++ (unlike the C ABI) is painful even before Qt's weird moc stuff gets going.


FWIW, I've made a very-early-alpha thing for making cross-platform apps with Nim: https://github.com/iffy/wiish


You mentioned it but, the strange meta object macro processing that qt depends up on, has been something I dislike. If I remember correctly GTK or other toolkits does not do anything similar.

And qt python bindings seems to be very poorly documented, same case with Java bindings.


The Qt Python bindings (PySide2 and PyQt5) do not need much documentation as they are just generated wrappers of Qt classes with the exact same API.


The Java bindings for Qt are also horribly out of date. This has killled off my largest OSS project to date, just before it was starting to become decent.


The first google hit for “qt nim” is [1] from 2017, so I think it’s safe to say it did not exist yet. The first hit for "wxwidgets nim" is [2], which has one open issue (since 2016): "Trouble building wxnim on win7".

Yes, time travel would solve most software development problems.

[1]: https://github.com/nim-lang/Nim/issues/6043 [2]: https://github.com/Araq/wxnim


He jokingly mentions Qt in the caption of the final picture.

I guess since he excludes GTK2 at the beginning for size concerns, wxWidgets and Qt would fall into the same category.


> He jokingly mentions Qt in the caption of the final picture.

well, he can keep joking and I can keep shipping Qt apps and everyone's happy


Except your users, they end up with your MBs.


I ship a Qt app. The installer is 135MB. 90MB of that is a demo video that comes with it. Nobody has ever complained.


yes, those poor users who end up with 70 megabytes to download, for something that comes with a large part of Qt, LLVM, libclang, multiple programming language implementation, support for plenty of network protocols... And I haven't even optimized what's inside the release package. ( https://github.com/OSSIA/score/releases)


Making a Qt app smaller would mean statically compiling the app and stripping the libraries but, hey, there’s an angry blog post that needs to get written.


Can you link us to your blog? I'd like to read that angry post if and/or when you post it.


I don't have an angry blog post about the size of cross-platform libraries.

Instead, I took the (longer) time to hand-tune Qt source and qconfig.h. My cross-platform desktop builds are under 2MB in a single executable, which appears to be something the OP wanted in the first place.


Oh, I think I misunderstood your original sentence. I thought you were saying there's an angry post that needs to be written about how to make a Qt app smaller by statically compiling the app and stripping the libraries. I was saying I would like to read the post detailing how.

But, now that I've thought about it for a few minutes, it does sound pretty straight forward. Unless Qt makes it difficult for some reason?


No, Qt doesn't make it difficult. We just live in a different era where it's more convenient to complain about frameworks than to dig in to the source/config files and modify them to suit your needs.

It's a Stack Overflow world, baby, we just live in it.


He does not like Qt because a simple window with a few buttons and sliders will end a big (in term of MB) application. He did not realize that one but another reason not to like Qt is that fact that they recreate the native look on each platform it's highly inefficient on macOS.


> another reason not to like Qt is that fact that they recreate the native look on each platform it's highly inefficient on macOS.

Given how everyone jumps on Electron these days, I don’t think thats a particular concern for anyone who just wants something to “simply be” cross-platform.


He complains that this creates enormous (in term of MB) application. My users sometimes have to rely on a lousy network connection to download. It can be because they are far away (China) or on a job. My users are in the event business and often have to rely on the WIFI of the hotel or the conference center.


It looks like Visix Galaxy is still alive and kicking, and it even supports UNIX, Windows, Windows NT, Macintosh, OpenVMS, and OS/2!

http://www.ambiencia.com/overviewgalaxytd.php


exactly, unless he really has something super special, QT should fix all his jokes. I don't use QT, but I think QT rarely has competition as far as cross-platform desktop GUI is concerned.

the only true "cross-platform" alternative is electron, which is a bit bloated and slow, but vscode is built on it, along with many others and worked fine. I personally prefer electron these days.


Qt and wxwidgets pretty much force you into using C++ and maybe python.

If you have to deal with all that baggage, then you might as well go build the UI layer native.


Huh?

https://wiki.qt.io/Language_Bindings

5.1 Qt for Python (PyQt)

5.2 Qt for Ring (RingQt)

5.3 Qt for Rust (Rust-Qt)

5.4 Qt Quick for Rust (qml-rust)

5.5 Qt Quick for Rust (qmlrs)

5.6 Qt for Crystal (qt5.cr)

5.7 Qt for Go (qt)

5.8 Qt for C#/Mono/.Net (QtSharp)

5.9 Qt for C#/Mono/.Net (Qml.Net)

5.10 Qt for D (QtE5)

5.11 Qt for Haskell (qtHaskell)

5.12 Qtah

5.13 Qt for Julia (QML.jl)

5.14 Qt Quick for Haskell (HsQML)

5.15 Qt Quick for OCaml (lablqml)

5.16 Qt Quick for Node.js (Brig)

5.17 QML bindings for Nelson language


Most of these are limited to the point of uselesness.


I ship nontrivial PyQt apps. PyQt can basically do anything Qt can do. Multiple inheritance of QWidgets can be dicey, but desired results can usually be achieved by defining mixins that don't subclass QWidget. It works brilliantly, far from "the point of uselessness". For me, cross platform GUIs are a solved problem, and I really can't wrap my head around all the noise to the contrary, or the claims that electron is what saved us.


Yeah that is why I said C++ and python...


Apologies, didn't see that


Python QT bindings are poorly documented, much of the documentation is out of date. Also it appears to me, far too much churn.


I don't use PyQt's documentation (wasn't even aware it really existed), it's such a literal wrapper that you can just use Qt's documentation.

And the only churn was a change about five years ago from a less pythonic API (using wrapped Qt types for most things) to a more pythonic one (using Python's native types where it makes sense). And that wasn't even that bad. Other than that it has no more churn than Qt itself does.


I am the author of Qml.Net.

With it, you have the full power of .NET Core and QML. There really isn't any limits.

https://github.com/qmlnet/qmlnet


I use the D bindings to qt regularly when I'm not using dlangui for GUI.


The Common Lisp bindings (EQL) are solid as well.


Quoting an article's (no doubt extensive) list of bindings for whatever library isn't a great way to start off a conversation about usable bindings in a given language. Bindings often exist, but they are not often any good.


What hyperbole! Writing a cross platform app in C++ using native UI libraries instead of something like Qt would be SO much more work!


Anyone got experience with this? https://webkit.org/wpe/

Here it is in use on raspberry pi https://medium.com/@decrocksam/building-wpe-webkit-for-raspb...

A long video on it: https://m.youtube.com/watch?v=klfE6m1oCkg

A short video on it: https://m.youtube.com/watch?v=wVSwkj9McCU

It says: "WPE is the reference WebKit port for embedded and low-consumption computer devices. It has been designed from the ground-up with performance, small footprint, accelerated content rendering, and simplicity of deployment in mind, bringing the excellence of the WebKit engine to countless platforms and target devices."

I'd be interested to know how to use it.


"GTK2 is too big"

"Just use Java or Electron"

I'm sorry, I just can't reconcile the logic here.


For the Java bit, I imagine that with modern Java versions with modules the app would be a lot smaller. The new Java versions are modular so you can include just what you use and I think it can even create a native package for installation. It should bring NodeNox 3 down from that 220MB package.


One warning: if you try to implement your own gui widgets in opengl, unless you're really careful you're not going to support accessibility tools such as screenreaders or Japanese/Chinese text input at all.


If people cared about those things they wouldn't be making crappy webapps with custom look n feel and no accessibility.


We already have browsers installed that are designed to render arbitrary cross-platform GUIs based on HTML/CSS.

Why can't I write a desktop application that just asks the OS for the users preferred browser and provides it with HTML/CSS and UI interaction callbacks / events? Render it in a native looking window.

We shouldn't need Electron at all! It's like we all have this fantastic rail transport network but insist on riding in our own trains.


Why do I need a browser just to show components on a screen? It's overkill to do that.


I agree, but we're not really talking about simple components on a screen. If that was the case, everybody would be happy to use tcl/tk, or swing or whatever.

Plus, it's not overkill when you get the browser for free.


Well, I'm happy to use Tcl/Tk -- although using it on a mobile device doesn't result in a usable touch-based interface.

Really, that's the crux of the problem is that there are different paradigms that are not just a little bit different but fundamentally different. This is especially annoying on my Chromebook running Android apps -- they very often expect you to be using a touch-based system without a keyboard. The way this works with a docked Chromebook and a mouse is the mouse is treated as a VERY precise finger touch.

Additionally, on Android and other touch-based systems you're usually not using a Window Manager so, for example, using an Android mail client on my Chromebook, I can't start the reply in a new window so that I can read the message in one window while simultaneously replying... and I especially can't have a bunch of unfinished replies while reading other emails to gather information for the reply.

Creating a meta-layer that can represent the fundamentally different modes from the same data is VERY difficult. HTML and CSS do a terrible job as well unless you model your HTML in a very specific way, which cannot accommodate all GUI semantics.


You never get the browser for free. It's a heavyweight rendering approach for what you're trying to do.


>Why can't I write a desktop application that just asks the OS for the users preferred browser and provides it with HTML/CSS and UI interaction callbacks / events? Render it in a native looking window.

You can:

- webview (I mentioned it elsewhere) https://github.com/zserge/webview - sciter https://www.google.com/search?client=firefox-b-1-d&q=sciter - ultralight https://ultralig.ht/

Granted it's not "user's preferred browser" but it fits the bill. They all have issues, largely solved by Electron packaging the browser engine with the binary, and even that isn't perfect.


These go a long way towards what I had in mind. Thanks for posting.


The most common reason I’ve heard is that devs want to be able to use cutting edge features and the update cycle for OS bundled browsers is too slow to accommodate that.

I find this argument a bit silly, because there are few applications that actually need said cutting edge features and even if you’re one of the handful there’s always polyfills, but maybe I’m missing something.


With Microsoft embracing Chromium as the built-in Windows rendering engine, enabling multiple Electron apps to run on a single instance, we're moving in the direction of Electron being the standard train your app can live in on any railroad.


This is a good point. Right now, web UIs on the desktop are effectively living in a world where DLLs were never invented.


I think he got it wrong when he quickly ruled out IMGUI, as you can use it to create a small app with next to no dependencies. He complains that you need to redraw your GUI at 60 FPS, but this is wrong, you should be able to draw with it only when needed. I am a big fan of Nuklear. I can write a tiny C app that compiles on macOS, Windows, iOS, and Android with it. The look and feel of Nuklear can be something you don't like, however.


> He complains that you need to redraw your GUI at 60 FPS, but this is wrong, you should be able to draw with it only when needed.

Yep, he did that, as stated here from TFA:

> The solution was to redraw only when needed: as a quick hack I introduced a global boolean doRedraw and set it to true only when an input event was received or the internal application state had been changed (e.g. the framebuffer had been updated). Then the drawing would only happen when doRedraw was set to true. Surely this could be done in a nicer way, but the general concept would be the same.

His issue was this...

> The second issue with text rendering was a harder nut to crack.

> I really don’t want to do a Donald E. Knuth here and spend too much time on a problem that has already been solved on the OS graphics library level in a perfectly satisfactory manner. I just want to call drawText() and be done with it!

How does Nuklear handle text rendering, layouts, fonts, etc?


He speaks about the 60 FPS when he tried NanoVG... I think he did not realize he could do that trick with IMGUI. For text rendering with Nuklear, you make a font atlas from a true type font, rasterizing the font is built in Nuklear with stb_truetype. That gives you a lot of freedom. You can load as many fonts as you need. There is also support to load a binary resource such as the TTF file from a base85 string; it's very handy. For layout it's immediate mode, so you describe it with code such as

nk_layout_row_dynamic(ctx, (float) row_height, 3); // a row of 3 buttons if (nk_button_label(ctx, "Previous")) ... if (nk_button_label(ctx, "Next")) ...

Here is small app I made with Nuklear: https://www.youtube.com/watch?v=MycIYcutlMA


If you need native look and feel: https://github.com/andlabs/libui

If you need HTML5 canvas-style drawing: I propose building an (abstract) SVG document and render with Skia. When part of the SVG document changes, that part will be redrawn by Skia, just like an interactive SVG in your browser. Disclaimer: I haven't tested this idea.


Adding my 2c (of anecdote) to this thread:

Andy Brice of successfulsoftware.net has a long-time product, Perfect Table Plan (computes seating plan for weddings, given various inputs) that used Qt (and C++), I've read, on his blog. PTP has been there for years now. Seems to be doing well, based on what he says about it. Don't know how good the Windows vs. Mac versions are, but at least they are there. His newer product HyperPlan may also be on the same stack.

https://www.perfecttableplan.com/html/about_us.html

No connection, just have followed the blog for long.


I know the author focused on Nim, but I wonder how Lazarus (or Delphi I guess) would fare.

Sadly it's FreePascal, but it really does look like the less bullshit platform to make cross-platform desktop applications.


Delphi was, and Lazarus is, amazingly well designed. Lazarus comes pretty close to a Swiss army GUI tool, and once you get to know it a little better, Object Pascal is actually a very nice language that rivals C++ (!) in power. It's still my secret weapon at work. If only the docs were better. Still keeping around a VM with Delphi 7 from 1999 just because documentation was sooo good then.


This is exactly why I say Electron is going to “win” in the cross platform GUI toolkit space. I do not think this is good thing. Cross platform GUI dev has been a train wreck as far back as I can remember. Contrast that with the immense amount of human years invested in making the browser a cross platform GUI runtime.

I’m sorry folks, 198MB menu bar apps is what we’re going to have unless a cross platform GUI effort equivalent to that of Chromium comes about.


FreePascal/Lazarus : cross platform native GUIs out of the box. Super small executables. No bloat.

For the love of God, check it out.


To add a little data on my experience last time I tried this, using UPX [0], you can get GTK+ 3 down to 9 MB. Most of the size of Qt comes from ICU, which can be feature selected to decrease its size [1]. With that and UPX, Qt can get down to 16 MB. And those can both be compressed another 30% with ZIP files for shipping.

While those aren't great numbers, I personally think it's tolerable for most usages.

[0] https://upx.github.io/

[1] https://ssl.icu-project.org/datacustom/index.html


I like the idea of having one c-sourcecode compiling on Linux, macOS and Windows. Hence, I have developed a platform independet GUI called Geeonx https://www.geeonx.org .

Versions for Linux and MacOS X are ready for download. The version for Windows will follow soon - I will speed up development if someone claps in his hands.


Hi all, one option might be HaxeUI (full disclosure, im the author!) :)

Its essentially a UI abstraction that delegates certain things "backends"

site: http://haxeui.org/ github: https://github.com/haxeui/haxeui-core discourse: https://community.haxeui.org/

It uses the Haxe language (haxe.org), here is a very small/simple/dumb sample of it "in action": https://www.youtube.com/watch?v=cijUTbMKMHI

It can use native components (wxWidgets, android, html5) but you can fairly easily extend it to use other "backends" (like Qt for example - i havent written that backend yet, but its something ill almost certainly do)... It can also handle drawing the components in a variety of methods (so called "composite backends").

Im currently aiming to get it out of alpha asap, and most work goes into "new-component-method" branches (these will become master shortly). Documentation is pretty slim at the moment, but something im actively working on, two examples that i just wrote up today in fact are:

https://github.com/haxeui/haxeui-guides/blob/master/custom-c...

and

https://github.com/haxeui/haxeui-guides/blob/master/modules....

Let me know if you have any questions! Ian Harrigan

Heres some other links / screens that may be useful:

https://twitter.com/IanHarrigan1982/status/11113481164338503...

https://twitter.com/IanHarrigan1982/status/10905353905980416...


Weird article. Why write an entire cross-platform GUI toolkit when he could port IUP to OS X? :)


These days, Xamarin looks interesting. Can target windows, Linux, Mac, Android and IOS. I have not used it yet but if I get a project that needs full Cross platform distribution, I would probably use xamarin with a F# code base where possible.


Given the other applications you chose to look at, I'm surprised you didn't also look at Audacity. It uses wxWidgets, which is a nice C++ cross-platform GUI framework. It wraps native controls on each platform it supports, and also has a "Generic" variant where it draws its own. It's not very heavy as these things go, and has a nice python binding called wxPython.

I'd check it out before rolling my own :)


By personal experience, wxWindows is "OK", but it's not a panacea. There are a ton of little quirks that will burn you when doing cross-platform development simply because native controls do not behave in the same way. HiDpi is a major pain with wxWindows (but then again, the way HiDpi is managed is a pain irrespective of the toolkit).

But if you do some forms and basic UI controls, wxWindows does the job egregiously. Looks the way it should be on all platforms.

It's funny an article from 2016 mentions issues about text rendering, because certainly we've been regressing in this area. I can spot QML and Electron apps by the broken text rendering alone. FF60+ with quantum has incorrect subpixel hinting and does not correctly hint at all sometimes.

Many of the mentioned apps int the article are "broken" in my eyes: I don't have perfect vision, and I do expect apps to follow the system text scaling (and they don't). For a "broken by design" example, see Darktable, which is awesome, and should do this by default, but the authors hard-coded a theme where literally every widget is styled for looks and not for function.

Nobody speaks about how the widgets should feel and interact, but that's exactly what feels off about "GTK" on windows or macos. QML, Electron and partly GTK3 brings that feeling to all platforms. My biggest letdown is QML, as many QT developers see it as the future so it has a larger adoption than it should have.

It breaks just about any rule in the book: poor behavior on any platform, noticeably slower, style not consistent with the platform, broken scrolling, broken text editing, broken text rendering...


> But if you do some forms and basic UI controls, wxWindows does the job egregiously. Looks the way it should be on all platforms.

Word choice? "Egregiously" means "Conspicuously bad or offensive." [0] The context suggests you intended to say "adequate for the purpose," for which "competently" is the correct term.[1]

[0] https://www.thefreedictionary.com/egregiously

[1] https://www.thefreedictionary.com/competently


I though he was being clever; "egregiously" means "in a manner consistent with being out of the herd". Bad or offensive for the goat-herd maybe, but perhaps not for the goat.


Thanks, I had a completely different meaning for this word in mind!


I also did. Given the Latin root (ēgregius, outstanding), I feel the pejorative connotation is out of place. The Italian term egregio definitely has a positive meaning, as it's also used to address people in letters.


I have filed numerous bug reports about Chrome's broken text rendering and hinting and had them closed as won't fix because they're too difficult to fix (note: not too difficult to reproduce, just too difficult to fix). I can't believe how low priority the correct displaying of the most important content in the window is to web browser developers.


Why does electron have broken text rendering? Surely the Chrome browser’s tendering does a good job? Or do you mean something like “it doesn’t match system defaults”?


Visual Studio Code on macOS right now has broken font rendering, since it uses Skia via Electron instead of macOS' native font rendering.

It's fixed in upstream Electron but until a fixed version is integrated into VSCode I have to live with (months of) broken font rendering.

It even makes me want to use Xcode somewhat. For all its flaws, its font rendering is just the system (working) one, and scrolling in Xcode is actually smooth 60fps instead of the laggy mess that is VSCode.


Not matching system settings (not just defaults, but the setting, i set the settings for a reason) is broken!


This. It's a bug to use a different text renderer than the system, because it will never look the same and with text this is very noticeable and irritating even to some people. You do _not_ want your core visual to be irritating.


> Surely the Chrome browser’s tendering does a good job?

it has always looked terrible to me when comparing to other desktop apps. All the fonts look more blurry.


Since many years I made a few application using wxWidgets, and the macOS part can have issues. While it's ok regarding the size of the app (in term of MB) you still drag and extensive library.



Oh, are we having this discussion again?


If anybody's interested in the previous discussion, which (imho) was pretty darned good: https://news.ycombinator.com/item?id=13952007


Mostly good article, but I don't appreciate the gratuitous dunking on web devs towards the bottom:

"so developers can use hipster technologies like HTML, CSS and JavaScript"

"the vast armies of newskool web developers who grew up on JavaScript and the DOM"

...especially when the author doesn't really appear to know what he's talking about in that space:

"And when things don’t quite work as expected, you can’t do much about it—short of maybe just switching to a different framework as a last attempt."

"and long-term maintenance will be a nightmare."

"web development technologies—which technically don’t provide any advantages over more traditional approaches"

There are legitimate criticisms of Electron as a choice for desktop apps, but that doesn't invalidate an entire domain's worth of developers.


In reality, JavaScript in 2019 on V8 - thanks to innovations like JIT compiling - is in almost the same ballpark as Java itself when it comes to performance. JavaScript itself is not what slows down JavaScript UIs.

What does slow down Web UIs is the DOM (whose rendering engine in Chromium is written in C++). The DOM is the most advanced layout engine ever created. It does an unbelievable amount of work to make interfaces resizable-by-default and adaptable-by-default, and yet is enormously flexible, allowing one to build virtually any box-based interface imaginable. This isn't simply so newcomers have an easier time. It frees application code to focus on the control logic and the structural side of the view, instead of messing with things like pixels and manual sizing, which makes application code more maintainable and reusable. I can place a piece of DOM in wildly different contexts, with wildly different amounts and types of content, and for the most part it will just respond as expected. This significantly reduces code complexity, which improves long-term maintainability and avoids bugs.

This of course comes with a cost. All of those implicit layout adjustments have overhead. The ability for your code to handle content you never thought it would encounter requires CPU time. That cost isn't worth it for certain applications. But it isn't a waste, or a sign of the moral decline of "kids these days". It's a conscious tradeoff that any good developer can weigh and consider for what it is.


What is this ridiculous obsession with executable size? How much time did this author spend chasing down alternatives to a measly 120MB? If they're working on art project then fair enough, but if they're working on a useful program then surely anything else they could have done with that time would have brought more value to end users than shaving off 3 cents' worth of disk space.


It's not ridiculous. We write off executable size as something that's irrelevant in an age where you can get a 4 TB drive for (what most of the HN audience would consider) peanuts, but it's not just disk space budget that's affected. Larger executables also mean:

- Longer start-up times (ridiculous things in 2019: a) SSD prices, b) the fact that it takes longer for an Electron todo app to load off a high-speed SSD than it took for basically the same application to load off my old Amiga's floppy drive)

- Fewer applications that you can run at the same time, higher chance of disk thrashing when resuming from suspend (bloated frameworks still have to make it to RAM, which yes, is also cheap and abundant, but load up a few VMs and see how abundant it seems then)

- Additional bandwidth used for delivering application updates

- Higher battery consumption if you use antivirus software and the like, because all those bits still need to be looked at.

- Sometimes it's just security theater, but not always -- a complex framework still has an attack surface even if your application doesn't use all of it.

These things save way more than a few cents' worth of disk space.


Sure. However long it takes to read 120mb off a disk (most likely less, if the application is only using some of the GTK dlls). 120mb of RAM. 120mb more to read when restoring from suspend. 120mb extra data use over your home internet connection. (I'm not going to talk about antivirus time because if you're using antivirus in 2019 you deserve whatever happens to you). It's still all irrelevant. Put a monetary or human-time value on it and compare to the cost of the application, or the development time, or a single crashing bug. Our programming culture's priorities are so far skewed from whats' actually important.


> I'm not going to talk about antivirus time because if you're using antivirus in 2019 you deserve whatever happens to you

If you develop enterprise applications (which many Electron applications are, in fact :-) ), you really have to talk about antivirus time. It's not something you can wish away. And it's not something that you should ascribe to customers being irrational, either. If malware compromises your users' data and it turns out you're not running antivirus software on your computers you're gonna pay way more than you'll ever save by using a big fancy framework.

Sure, it's a bad idea (in strictly technical terms) but you can't just go to your customers with a straight face and ask them to stop running antivirus software because it's 2019.

> Put a monetary or human-time value on it and compare to the cost of the application, or the development time, or a single crashing bug

You say it as if these were independent, but they're not. Debugging performance issues (the critical kind, that make customers yell at you and utter words like "money" and "back") in Electron applications is a mini-project in and of itself. Complex frameworks (I'm not picking on Electron in particular) are cool to quickly develop against, but not cool to troubleshoot, and once you start going off the beaten path, it's not as fun.

Of course, sometimes it's a justified choice, I'm not in the "Real Programmers don't use Electron" camp. But the non-technical aspect of this engineering choice is slippery, as non-technical aspects always are. Sometimes it's the right choice in terms of organization expertise and whatnot, but sometimes it just appeases executive impatience, at the expense of customer experience.


> If you develop enterprise applications (which many Electron applications are, in fact :-) ), you really have to talk about antivirus time. It's not something you can wish away.

In enterprise applications you totally can just wish AV away by turning it off. It's useless at best and mostly serves to just gum up the works and slow things down without providing tangible benefit. There are much better ways to handle security in an org.


> Debugging performance issues (the critical kind, that make customers yell at you and utter words like "money" and "back") in Electron applications is a mini-project in and of itself. Complex frameworks (I'm not picking on Electron in particular) are cool to quickly develop against, but not cool to troubleshoot, and once you start going off the beaten path, it's not as fun.

You can do a lot of debugging and performance tuning in the amount of time it takes to write a custom non-framework GUI. But you're right that it's much less fun for the programmer, which I suspect is the real motivation here.


All that multiplied by the number of customers. If you don't value your customers, then they are all "irrelevant".

> Our programming culture's priorities are so far skewed from whats' actually important.

Indeed, that's why there are so many electron based bloatware being developed.


All development effort is multiplied by number of customers though. Like, if you put that time and effort into developing a new useful feature, the value of that is multiplied by number of customers too.


xfer means to multiply the cost of the wasted resources by the number of customers, since it is they who will have to waste those resources, not you. On the other hand the resources spent to implement the new useful feature will only be used by you, not your customers, so you do not get to multiply that.


This sort of "who cares" thinking gives us lazy bloatware like Electron.


AKA useful software that actually does something users want, rather than some kind of ascetic practice exercise. Yes, yes it does.


Earth's resources are not infinite, nor its ability to tolerate pollution.

Less importantly, my computer's resources are also not infinite. Yes, maybe your Electron app does something I want, but guess what, there are numerous other things I also want to do, and it is a bit silly that an IRC replacement now takes half of my computing power and manages to be less responsive than the stuff I used 20 years ago, in the computers of 20 years ago.


Well, not really. I hate on Electron not because of its size on disk, but its runtime memory footprint. Things like Skype in the background using 500MB, an Autodesk update notifier sitting silently in the tray using 350MB etc. all add up to a few GB of main memory you suddenly don't have. And these numbers are real, by the way.


It's kinda weird how little you have to do with 32 GB (!) of RAM until Windows starts to complain about not having enough free memory and you-better-close-some-applications-right-now! I remember when a 1 GB memory upgrade was something, and back then I could even play a game on 512 MB of memory and occassionally alt-tab to a web browser for cheats... nowadays a web browser on 512 MB RAM is virtually impossible.

(Edit: I realize this complaint is quite old, but from the age where hundreds-of-MB main memory were mainstream we have seen very little actual improvement in GUI fancyness, yet a massive explosion in CPU and memory use, and often even heavily deteriorated responsiveness. That doesn't hold going from the "couple of megs" to "hundreds of megs" age.)


> nowadays a web browser on 512 MB RAM is virtually impossible.

Right now my Palemoon browser uses less than 240Mb. It is possible, just don't do stupid things (like keeping 4385972Z38947 tabs open instead of using bookmarks) or cut out a little the eye-candy and the the "geek status symbol" stuff.


That's kinda the fault of the developer. Electron itself isn't very large and I've seen very well crafted electron apps. The fact that slack uses 1-2gb memory is definitely on slack.


No, lazy bloatware like Electron isn't necessary to create useful software that actually does something users want. These two are independent of each other, you can create useful software that actually does something users want and still have it be lightweight on resources and fast.


Electron doesn’t actually do what I want: I want apps that fit in with the rest of my system and don’t use excessive resources.


I don't consider text editors that take 10,000 times the necessary resources to run without lag to be useful.


[deleted]


> If personal storage units were given away for free, you might argue that it doesn't make sense to organize your stuff, or remove stuff you don't need anymore, and you would be wrong. The least important reason to consider is to conserve disk and bandwidth; the most important is to reduce risk by reducing surface area. Small, sleek and efficient is mostly about reducing cognitive load, even if it had it's roots in mechanical resource conservation.

I agree with that much, but using GTK+ in the normal way for your language has a much lower cognitive load than any proposed alternative.

> BTW I work on a project that made this same argument years ago, writ large, for the CI system they built. "Size doesn't matter; just throw more money at instances; its cheaper than spending dev resources to make it efficient." So, now we have a development pipeline that uses more EC2 instances than production, by a factor of about 100. The build no longer runs well on (very fast) dev machines, and takes 30 minutes even on xlarge instances. The build is enormous, complex, and slow, and it was allowed to get that way because someone made the same argument you are making against a strawman.

That's a textbook slippery slope fallacy. If and when resource consumption becomes a significant issue for your use case, take measures to address that. Size absolutely can matter. But 120mb does not matter.


120 MB would be enough for me to choose an alternative to your application.


Why? There are computers older than I am for which that's an insignificant amount.


Because it is a waste of resources and an extremely good indicator (as shown by the replies to these posts) that the low standards the developers of these applications have towards their code.

As an example (which i like to point out, but also sad to note that it is only a minority, showing the state of modern desktop software) i bought Total Commander exactly because of how small, lightweight and responsive it is (the entire installation is 14MB, the application itself uses at this moment 3.5MB of RAM - although often goes up to 8MB, depending on what i'm doing and how many tabs i have open - which btw is around 5 times more than the Windows 10 calculator!) while providing a ton of functionality (...certainly more than a calculator :-P). And it isn't like it was written in direct oh-so-hard-to-use pure Win32 API either, the 32bit version is written in Delphi which has a very rich framework and the 64bit version is written in Lazarus (which is pretty much an open source Delphi) and beyond those it uses several additional libraries. It just didn't make choices that were wasteful from the start.

So here is a case of someone making money (from me, but also others since its lightness and power are pretty much what everyone cites about it) explicitly because they cared about their program's resource usage.

I just really really wish more desktop software would do the same. Sadly it only goes in the opposite direction.


Curiously, there are only a handful of computers, ever, that were older than I am. And I'm not that old :)


The King James bible is about 4mb of UTF-8 text.

If your business code is 300k, or about 1/13 of that, then slapping a whopping 30 bibles of bullshit you will definitely not use for a 2 pane thing with a couple buttons and some renderer output on one side is not an insignificant investment.


Why? Is a medieval scribe hand-copying your GUI libraries?

A bible costs maybe $15, which is about 60GB's worth of storage - that seems like a more relevant comparison.


You miss the point.

And you are missing it because you're OK with jamming your code right inside 400 times more foreign code in order to display a cute window with two panes in it.

Do please make a civil effort to understand there's people who are not ok with it. People like OP, who feels devoting 47 bibles of code to displaying a taskbar widget is not OK.

Or like me, who actually likes to know exactly what is my code doing.


It's a bit rich to be asking someone to be civil in the same post where you turn your non-point into a personal attack. If there's a point I'm missing then make that point. Don't just talk about "number of bibles" as though it means something.


Given you confuse statements of fact with personal attacks, this conversation no longer makes no sense. Bye.


Electron usage has forced me to spend some of my yearly dev budget on a 32GB machine; this comes to an extra $400 if purchased preinstalled. Now, had I not relied on so many Electron apps I probably wouldn't have required a new laptop at all. Memory management (or what I like to call memory hygiene in cases like these) is a concern. For far too long developers have brushed aside the memory usage of their applications not thinking of the cost on their end users. This has real negative effects on the user experience. This isn't confined to Electron though; many other apps also use an enormous amount of memory as well. It is a general problem.


Developers assuming that all users have hardware and internet speeds anywhere close to as good as their own is a huge problem.

Not only is there a huge chunk of people who are using low-to-midrange laptops ranging anywhere between old and ancient, but manufacturers are still selling brand new machines with CPU power and RAM roughly on par with the average laptop from 2007 (C2D class CPU, 2-4GB RAM, 5400RPM HD). Those users aren’t going away any time soon, and by casting resource consumption aside as a total non-issue, developers are also casting these users aside.


How is 120MB in any way, shape or form "measly"? It is exactly this kind of thinking that delivered unto us the absolute monstrosities we see in the wild.


Well, just loading 120MB executable from an SD card to run it would take 6s in ideal case on the tablet that I use, before it even gets to execution. That's 10s+ startup times for Electron app. Meanwhile my 2MB static C app starts in fractions of a second right after boot.

Storage space is not the only consideration. Storage speed may also be limited.


For making something absolutely HUGE like Blender or a DAW (which he uses as examples) I can't see why size makes a difference at all. It doesn't matter whether blender takes half a gig or five, or whether it starts in one second or five .

On the other hand if you make a VST plugin or a chat application THEN startup time of 0.1s instead of 1s makes a huge difference.

So I think size/startup time really is important, but I fail to see why he chooses these huge applications as examples (because for them it doesn't matter). I suppose he chose them as they were "state of the art" in terms of complexity etc - but perhaps he should look for smaller aps (such as JUCE plugins) to see the state of the art in terms of size/load time.


Believe it or not there are countries where people trade sex for power to charge their phones. I'm sure the resources wasted by bloated apps are precious to them.




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

Search: