While Electron's popularity was a boon to the desktop app scene, I keep on dreaming that JavaFX applications made with Kotlin, jlink, Gluon's scene builder (or maybe even something better) will gain enough popularity to attract a healthy open source community for cross platform desktop apps.
It feels like the tools are almost where they need to be and finally coming together!
OK, so question time: I haven't done any Java (let alone Kotlin) coding now for what seems like ages, but will need to implement a relatively simple, yet cross-platform client for my upcoming application. It will probably sound extremely silly, but were I to write a GUI that speaks to a REST API, where should I start doing my research?
If you have more recent experience on C++, Python or Javascript then you should be looking into Qt, PyQt, Electron (respectively) or other alternatives first, but if you're willing to try the Java environment you could look into the following components to get you started:
-Kotlin to speed up development
-Gradle as a dependency manager
-Retrofit + OkHTTP to create a type safe backend API definition
-JavaFX for the GUI components
-Gluon's scene builder if you like creating your FX views in xml, with a visual editor
-RX as a powerful library for async tasks
-Gson or Jackson as a JSON parsing library
-IntelliJ if you like coding with IDEs, for its massive refactoring capabilities
It's a lot to take in if you're unfamiliar, but together they all come to form really solid desktop applications.
Even so, Java is now at a place where you can ship self-contained, zero-dependency applications that are comparable in size to other compiled languages (and superior to web-hybrid options like Electron).
For cross-platform desktop GUI apps, I would argue that JavaFX combined with Java 9 modularization is hands-down the best choice available today.
Electron is succeeding in the desktop GUI space because it tears down the barriers to desktop app development. While the author's article is excellent, when it comes to Electron, he (like most engineers) is still missing the point: the choice between Electron and its alternatives doesn't pivot on file size.
Well, will see how Electron will pan out in the end. While I dislike default Java Swing GUI (it can be made easily to look native but many devs previously did not do it), JavaFX can be made to look like anything with almost weblike feel to development and animations.
Now, more than the looks I dislike the slowness and utterly unacceptable memory Electron apps consume. I ditched Electron and VSCode (it is a little better than Atom) because I don`t want to have my text editor eat 500mb ram to open 1 medium file and crash on large ones. Same for Slack and other Electron apps. And it is not even funny to see dev console when some Atom plugin or whatever crash. I`m interested how many devs also ditched this two editors ONLY because of Electron bloat.
I'm using JetBrains IDEs now instead. They're definitely not lightweight, but it's built in functionality is generally a lot more stable than what I get with text editors + a lot of plugins.
My cursor lagging is not a small concern. It disrupts the flow between code being re/written and the mental model I'm trying to pour out.
Text input lag is an issue every editor has to deal with, and many go to extreme lengths to optimise it. Electron makes it far more difficult than most editors to fix, and every lag issue opened on VS Code seems to get decent attention, (and patches), and comparisons to Sublime Text.
Seems to be something I'm not alone in caring about.
I've honestly seen only one properly written Electron app and it's VSCode. Everything else electron sucks. VSCode is not great either but it's much better than say, Atom or Slack.
Sure, but Discord's web app and their native app are basically equivalent. The native app gives a little more system integration (like global hotkeys and direct access to sound hardware) but fundamentally the Discord app is just a webview.
I don't think anyone doubts that a high-quality website wrapped in a webview won't be at least the same quality. The question is whether "web-native" platforms can do more than just be a branded browser.
I was curious as I've never found a standalone visual git client I liked as much as IntelliJ's integrated one. So I downloaded it, found it was 1/4 of a GB and wouldn't look at a local repo without logging in to a web service. Deleted.
I still haven't found anything better than IntelliJ's triple column view for resolving merge conflicts. Is there anything similar in a more lightweight editor?
Some years ago I was evaluating GUI git clients (the landscape has changed since) for rather simple flows and found SmartGitHg simple enough to setup and explain in under an hour and powerful enough not to drop to a shell. No affiliation here.
Another anecdote; your comment is the only one I've ever noticed that appears to be defending Slack. From an outsider looking in, I'm not sure why it is so popular.
It's popular because technical superiority isn't why people use software.
For example, Spotify eats 100% CPU if I leave it open for 24 hours yet I don't think I've met someone in the last year that doesn't have Spotify running on their computer.
Sure, but more companies have the story of needing a web app anyway which requires a specific tech stack. So you can either maintain two tech stacks or you can port your webapp to native.
Having a beautiful, easy to develop, and easy to maintain native stack means nothing when you don't have an answer to, "How do we then reuse our code in a browser?".
Electron sits in the same hybrid space as Cordova/Phonegap, and will suffer the same fate once React Native, or something similar, starts eating its lunch.
There are some ReactNative alternatives calling themselves "native" that are only "native looking css in a webview". The future will probably only get more ambiguous.
It’s really not clear what the electron app even provides over the same app in chrome. Its own icon, sure, but the behavior is just as bad as on the web—just take slack for example.
It offers access to file system and system resources as well as multi platform build support. Developers like all people will whine over anything. For students and indie devs who have little time, support, and resources things like electron are great
Right, but does eg slack actually use any of that? It’s not a great native client by any stretch—it doesn’t use a native UI, it’s not particularly snappy, and it doesn’t do any special integration. So, it seems that electron is mostly a way to distinguish certain sites from others, not that they provide a better experience.
Granted I do like the distinct app icon. But electron should mean more than that to qualify as meaningfully native.
While everyone is excited about how this helps desktop app development, this is also going to simplify server deploys. If you've got a full java stack, you won't need to do anything to provision a server.
So, after "optimizations [...] to further reduce the resulting bundle size", a Java command-line "Hello World" is still 21.7 MB. I've found a Node.js version (using node-packer [1]) to be about the same size.
However, as mentioned in the article, "Hello World" in Go is an order of magnitude smaller. The article may be right that Java is "the best choice available" for cross-platform GUI apps, but for cross-platform command-line tools, I think Go is currently the best option. IMO Go provides the best tradeoff between ease of development, ease of distribution and runtime performance.
Since Go and Electron are mentioned, let me offer a web UI library for Go: https://github.com/zserge/webview (I know UI has been a problem for Go apps for a while and is often a stopper when it comes to writing desktop apps in Go).
The library creates a full-screen webview window and lets you write UI code in HTML5/CSS/JS connecting it to the core app logic written Go. It provides JS-to-Go bindings allowing to call Go code from JS and vice versa.
The whole library is a single header file of ~800LOC with a thin Go wrapper. It supports Windows 7+, MacOS, Linux and OpenBSD.
Executables are 5-10MB in size and take about the same amount of RAM. No external libraries are used on Windows and MacOS, on Linux gtk-webkit is required, but it is typically one "apt-get" command to run.
On Windows 7 SP1 it uses IE11. Same on Windows 10. On some Windows 8 it might use IE10, which is still not that bad.
Sorry, can't tell much about xls/doc. It's aimed to be a web UI for your app. Normally, you app would be a web server then. So if you want to handle certain requests and open external apps - you surely can do it.
People need to stop comparing app sizes of "Hello World" apps and use a more real, more complete application as an example. One that does most of the things that one would do in the platform, for starters.
If we "compare by Hello World" then Assembly/handwritten bytecode would win, but what's the point?
No. 2.17 MB is NOT enormous. Usually there is no runtime library. In contrast, C or C++ runtime libraries can easily exceed that size. For example, vc_redist.x64.exe is 13.9 MB.
It's a matter of platform and the libraries that you're using.
After all, back in the days we had 360k floppy disks, and executable written in C which did much more than just printing out "Hello world" would fit comfortably into less than half of that.
Modern C and C++ runtimes are bloated, because a 2MB executable isn't considered huge anymore and dynamic linking is common.
But you can have a 5k static executable printing "hello world" on Linux if you just trade in your stdlibc to musl.
People have also managed to use musl with Rust to produce pretty small executables:
https://lifthrasiir.github.io/rustlog/why-is-a-rust-executab...
Go runtime is included in the executable. C or C++ do not automatically do that when writing a simple "hello world" and compiling it into an executable. stdio isn't statically linked by default.
And when rid of debugging symbols, even when importing the fmt package :
package main
import "fmt"
func main() {
fmt.Print("Hello World")
}
Java and Node need to ship their own virtual machine while native code does not (others mentioned that runtime may be dynamically linked). VM startup time is ludicrously high compared to execution time of "userspace" code in CLI tool, making such rintimes no-go for CLI tools (except for web devs, apparently).
I want to use JavaFX to develop cross-platform apps but I feel JVM uses too much memory even for little things.
It's been a while since I've used Java to program, has the memory situation changed? or are there any other solutions for lowering the JVM memory usage?
Java will use as much memory as you give it. Higher heap size is better for performance up to around 32GB. For most Java apps you can limit heap to 256M or less with little consequence.
AFAIK Java uses less ram than Python and JavaScript, only common languages that beat it are Golang and C/C++
I used Swing Java applications on a computer with 512 MB RAM. Sure, Java eats more than C++, but it should be pretty in line with JavaScript which is a very popular choice nowadays.
This looks pretty awesome. I haven't used JavaFX before, but if it's easy enough to deliver high quality UX with it, I'll be using this for any side project desktop apps I end up working on.
TFA reads like GCJ does not exist, a classic lie by omission. Don't become a victim of misinformation!
Compiling to small, native binaries (i.e. JRE not needed) is possible since at least 10 years ago. Let's examine this application as an example: http://sancho-gui.sf.net
It is possible using an AOT compiler for Java, like Codename One or Robot VM.
So far Oracle has shown little interest into integrating such features into OpenJDK, but the ongoing efforts to add AOT compilation to it, might become a possible solution.
15 years since I last looked at Java for Desktop Apps and shipping as binary. I remember there were also GCJ as the commercial JET alternative.
Graal and Truffle are progressing along. I wonder what happen to SubstrateVM, which allows AOT of Java. I assume with SVM the binary size can be further reduced and much faster startup time.
Oracle have broken and delayed releases of Java so some people can get slimmer binaries? Hardly seems like a good trade off when storage is the cheapest it’s ever been.
It's not about storage. Most desktops don't have a JRE installed and downloading the full non-modular JRE and installing it before being able to run the program is a hassle compared to providing a stripped down, self sufficient, linked version of the app that's one third in size.
Who cares about desktop apps? Most Java development is done on the server where the size of your runtime isn't a constraint. Breaking reflection, delaying language features, releases, etc is a very poor tradeoff for the module system that has been delivered.
I'm not the OP, but I assume hi-DPI support means that applications scale up their GUI sizes appropriately based on the DPI.
When I use a hi-DPI display (like 4K displays), a lot of old software renders text and widgets too small to see, because they were programmed to display things as so-many pixels high, without concern for DPI. It's frequently a problem with old video games, though it affects regular applications too.
What difference does it make if the standard resolution is Hi-DPI or not? Can you visually tell the difference between pixel doubling and other methods of designing for Hi-DPI?
Except that isn't actually portable Go code, because you are using an unsupported function that can be removed at any time.
"The print built-in function formats its arguments in an implementation-specific way and writes the result to standard error. Print is useful for bootstrapping and debugging; it is not guaranteed to stay in the language."
Don't forget to pass -ldflags "-s -w" to `go build`.
Debugging symbols are over 50% of most Go binaries I see, and you don't even need them to get stack traces from panics.
Combined with `upx --ultra-brute`, you can get static Go binaries down to about 12-15% of their plain `go build` size in my experience. (This also assumes CGO_ENABLED=0)
I tend to view it more as a regressor. Golang is a conservative retrenchment towards Java pre-1.5 in a lot of ways. (And that may be fine for some use cases; I get the appeal even if I think it's misguided.)
Sure, there certainly is: it looks easy at first blush and scales moderately well. And that's fine, if you understand its drawbacks, and what Go aficionados try hard not to address is that Golang has a severe complexity wall. It is a large reason, along with faddish trendiness, why the Go universe clings so heavily to microservices: because the Golang is structured lends itself to writing messy code that is more easily combated by splitting into different systems rather than just writing modular code that respects encapsulation (in part because its type system is lousy, in part because error handling with deeply nested trees is harder than it needs to be, etc.). That this also creates additional problems--request tracing is an ongoing tire fire--is often elided a little bit, too.
In my experience, Go exhibits human-scaling problems long before even dynamically typed languages and significantly before Java, Kotlin, or the like. And the arguments to deployment are defanged both by Docker and by that it's usually not the developer who picks it who ends up building the CM around it in the first place (that's why they hire people like me, and why I have had to become uncomfortably familiar with Golang, its ecosystem, and the habits of your average Golang developer: because the person running the systems it runs on is inevitably the backstop for when those programs spit the bit).
But in the five-minute-demo-to-make-production-decisions universe, it plays really well.
Hey! You win the worthless example competition! See the front desk for your prize. How about comparing a full stack, monolith app in Java vs Golang? While you’re at it, don’t just compare binaries. Compare how well it handles concurrency. Compare how well it handles templates. Or how smoothly it handles DB interaction. Then look at all this and compare the population of Golang vs Java devs. Compare how well you can leverage existing language knowledge while working on a major mobile platform too like Android.
Binary size for a hello world app means little to nothing. I can beat that with Bash: echo “hello, world!” Compare to real applications.
Would you please not reply to a bad HN comment by making the thread even worse? The site guidelines explicitly ask you not to do this.
Your account unfortunately stands out in my mind as one which has posted many nasty comments to HN over the years (as well as many good ones), so glass houses and all that. If you would read https://news.ycombinator.com/newsguidelines.html and post only scrupulously respectful comments from now on, we'd appreciate it.
“Zero dependency” after you install a 80MB JRE. You keep using this word. I don’t think it means what you think it does. Statically linked C is zero dependency. Go is zero dependency. Copy a binary to the target system and it runs. There’s nothing else to install.
It gets a little fuzzy. Go and C are only zero dependency once you have their platforms installed (the OS). The JRE is only a little on top of that, ships with some systems out of the box, and is generally ubiquitous enough that you can probably rely on it being present it over a particular OS being present.
Ita not really zero cost, but neither is an app that only has binaries for an OS you don't run.
It feels like the tools are almost where they need to be and finally coming together!
-Kotlin to speed up development
-Gradle as a dependency manager
-Retrofit + OkHTTP to create a type safe backend API definition
-JavaFX for the GUI components
-Gluon's scene builder if you like creating your FX views in xml, with a visual editor
-RX as a powerful library for async tasks
-Gson or Jackson as a JSON parsing library
-IntelliJ if you like coding with IDEs, for its massive refactoring capabilities
It's a lot to take in if you're unfamiliar, but together they all come to form really solid desktop applications.
For cross-platform desktop GUI apps, I would argue that JavaFX combined with Java 9 modularization is hands-down the best choice available today.
Electron is succeeding in the desktop GUI space because it tears down the barriers to desktop app development. While the author's article is excellent, when it comes to Electron, he (like most engineers) is still missing the point: the choice between Electron and its alternatives doesn't pivot on file size.
Text input lag is an issue every editor has to deal with, and many go to extreme lengths to optimise it. Electron makes it far more difficult than most editors to fix, and every lag issue opened on VS Code seems to get decent attention, (and patches), and comparisons to Sublime Text.
Seems to be something I'm not alone in caring about.
Shocking, when I look back at it.
I've honestly seen only one properly written Electron app and it's VSCode. Everything else electron sucks. VSCode is not great either but it's much better than say, Atom or Slack.
I don't think anyone doubts that a high-quality website wrapped in a webview won't be at least the same quality. The question is whether "web-native" platforms can do more than just be a branded browser.
But I assume these apps have spent a considerable amount of time in optimizing electron, which not everyone can do.
0: http://meldmerge.org/help/resolving-conflicts.html
For example, Spotify eats 100% CPU if I leave it open for 24 hours yet I don't think I've met someone in the last year that doesn't have Spotify running on their computer.
Yes, then it replaces them with the barriers to web app development.
Having a beautiful, easy to develop, and easy to maintain native stack means nothing when you don't have an answer to, "How do we then reuse our code in a browser?".
Use the browser for what it was meant for, hyperactive documents.
Everything that matters is on the backend accessed via Web APIs.
Granted I do like the distinct app icon. But electron should mean more than that to qualify as meaningfully native.
So Slack gets an icon on the homescreen and possibly offline notification + notification integration with the OS.
That might be pretty limited from a technical perspective, but it's a massive product thing from a product perspective.
Also, it's possible they may use file access for caching/storage etc..
However, as mentioned in the article, "Hello World" in Go is an order of magnitude smaller. The article may be right that Java is "the best choice available" for cross-platform GUI apps, but for cross-platform command-line tools, I think Go is currently the best option. IMO Go provides the best tradeoff between ease of development, ease of distribution and runtime performance.
[1] https://github.com/pmq20/node-packer
The library creates a full-screen webview window and lets you write UI code in HTML5/CSS/JS connecting it to the core app logic written Go. It provides JS-to-Go bindings allowing to call Go code from JS and vice versa.
The whole library is a single header file of ~800LOC with a thin Go wrapper. It supports Windows 7+, MacOS, Linux and OpenBSD.
Executables are 5-10MB in size and take about the same amount of RAM. No external libraries are used on Windows and MacOS, on Linux gtk-webkit is required, but it is typically one "apt-get" command to run.
Another question is around intercepting xls/doc responses to load them into office. Is there a way to do this with this framework?
Thanks!
Sorry, can't tell much about xls/doc. It's aimed to be a web UI for your app. Normally, you app would be a web server then. So if you want to handle certain requests and open external apps - you surely can do it.
If we "compare by Hello World" then Assembly/handwritten bytecode would win, but what's the point?
After all, back in the days we had 360k floppy disks, and executable written in C which did much more than just printing out "Hello world" would fit comfortably into less than half of that.
Modern C and C++ runtimes are bloated, because a 2MB executable isn't considered huge anymore and dynamic linking is common.
But you can have a 5k static executable printing "hello world" on Linux if you just trade in your stdlibc to musl. People have also managed to use musl with Rust to produce pretty small executables: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executab...
I just tried building a statically linked 'hello world' c++ program, and co-incidentally, the binary also happened to be 2.1 MB!
'g++ -static -o hello hello.cpp' produces a binary of 2191112 bytes (Linux x64). Stripping it of debug symbols leaves a 1.7 MB file.And when rid of debugging symbols, even when importing the fmt package :
go build -ldflags "-s -w" hello.gois 1.3MB .
It's been a while since I've used Java to program, has the memory situation changed? or are there any other solutions for lowering the JVM memory usage?
AFAIK Java uses less ram than Python and JavaScript, only common languages that beat it are Golang and C/C++
http://www.jesperdj.com/2015/10/04/project-valhalla-value-ty...
Java applications use much less memory, unless their coders weren't paying attention during algorithms and datastructures lectures.
Compiling to small, native binaries (i.e. JRE not needed) is possible since at least 10 years ago. Let's examine this application as an example: http://sancho-gui.sf.net
So far Oracle has shown little interest into integrating such features into OpenJDK, but the ongoing efforts to add AOT compilation to it, might become a possible solution.
Given the already large ecosystem built on these lanuages, its unlikely they'll pivot to a JVM based system.
As others have pointed out you could compile the Java code to native code before submitting the app, the way C# apps are put in the store.
Graal and Truffle are progressing along. I wonder what happen to SubstrateVM, which allows AOT of Java. I assume with SVM the binary size can be further reduced and much faster startup time.
And server apps don't really switch that fast to newest Java release. Only now we're seeing JDK7 based things for example.
It's frustrating how we're wallowing in problems that had already been solved for most of my career.
Just in case you aren't, what do you think is required for a platform to support Hi-DPI displays?
When I use a hi-DPI display (like 4K displays), a lot of old software renders text and widgets too small to see, because they were programmed to display things as so-many pixels high, without concern for DPI. It's frequently a problem with old video games, though it affects regular applications too.
Nitpick but hello-world in Go :
is < 1MB on most computers (900KB on windows). No need to import the "fmt" package."The print built-in function formats its arguments in an implementation-specific way and writes the result to standard error. Print is useful for bootstrapping and debugging; it is not guaranteed to stay in the language."
https://golang.org/pkg/builtin/
Debugging symbols are over 50% of most Go binaries I see, and you don't even need them to get stack traces from panics.
Combined with `upx --ultra-brute`, you can get static Go binaries down to about 12-15% of their plain `go build` size in my experience. (This also assumes CGO_ENABLED=0)
In my experience, Go exhibits human-scaling problems long before even dynamically typed languages and significantly before Java, Kotlin, or the like. And the arguments to deployment are defanged both by Docker and by that it's usually not the developer who picks it who ends up building the CM around it in the first place (that's why they hire people like me, and why I have had to become uncomfortably familiar with Golang, its ecosystem, and the habits of your average Golang developer: because the person running the systems it runs on is inevitably the backstop for when those programs spit the bit).
But in the five-minute-demo-to-make-production-decisions universe, it plays really well.
Binary size for a hello world app means little to nothing. I can beat that with Bash: echo “hello, world!” Compare to real applications.
https://news.ycombinator.com/newsguidelines.html
Your account unfortunately stands out in my mind as one which has posted many nasty comments to HN over the years (as well as many good ones), so glass houses and all that. If you would read https://news.ycombinator.com/newsguidelines.html and post only scrupulously respectful comments from now on, we'd appreciate it.
I'm just quoting the original article. If you want to get mad at someone be mad at the OP. The whole point of the post is executable sizes.
Ita not really zero cost, but neither is an app that only has binaries for an OS you don't run.