So now that my 100-episode Electron Adventure series is coming to a close, I want to spend the final two episodes on a retrospective. This episode will be about Electron, and the next one about the series itself.
Cross-platform GUI development has always been a huge pain. Your choices were:
- write the app multiple times, once for each platform, in multiple different low-level languages
- use some "cross-platform" lowest common denominator solution like various Java toolkits that results in an awful experience for everyone
- just drop the whole idea and make the app single platform
Meanwhile, web development was ridiculously easy, and ridiculously powerful, and it was all cross-platform by definition.
So the whole idea behind Electron was basically "screw all that, we'll just ship a whole browser with the app". And it worked. So well that today you'd be very hard pressed to name any decent cross-platform GUI apps that aren't Electron apps.
Whenever anyone mentions Electron, it instantly triggers haters who absolutely cannot stand the idea of bundling the whole browser. The haters are especially bitter because they are losing utterly, and they cannot even begin to offer any alternatives.
The first objection is that it takes too much space. This was always a stupid argument, and it got even worse as time goes. Even the shitty entry level laptops have 256GB+ disks these days, so if you download 100 Electron apps at 100MB each - not something a typical user does - even that's less than 4% of your laptop's disk. And this becomes less and less relevant as time goes.
But really this isn't Electron specific issue. The whole software world moved hard to "bundle all the things" mode.
The days where an app would just use whatever happened to be installed on a local machine are gone. Every app comes with a
package-lock.json or its equivalent specifying exact versions of every single dependency.
node_modules, or some browser with Electron, more and more apps just bundle a whole Linux distribution with Docker, and run that. Or they bundle a whole collection of Dockers for different parts of the app, with multiple Linux distributions inside. Some recent languages like Go basically decided to not even support traditional shared libraries - if you use some code, you have to bundle it into a single executable.
Electron deciding to bundle the browser back in 2013 was ahead of its times, but now this is hardly a controversial decision. Everyone bundles everything.
Over the series, we tried a huge number of alternatives to Electron, and found all of them to be pretty bad.
There's two kinds of alternatives to Electron. The first is all the other web-based solutions that just don't bundle the browser, and use whatever's installed.
In principle this works, as long as the user has a recent version of Chrome or such, like with Ferrum. But they need to be strict about it, and if no Chrome (or Chromium) is found, they need to just tell the user to install it.
Even that doesn't quite solve the problem. Electron bundles two things - browser and node. Even if we use user's browser, we still need to bundle the backend language, and none of the languages have easy cross-platform bundling story. OSX comes with really old versions of Ruby and Python, Windows comes with .NET, Linux comes with whatever each distro decides (at least some sort of Python), none of them were made with portability in mind. It would be great if we could just ship an app in a Docker to the user, just like we can with servers, but we're not there yet.
Anyway, every alternative we've tried that used OS-bundled HTML view, like Safari, os whatever Qt has, and so on - all of them have been a total disaster. The web is easy to develop for, as it's basically all Chrome, or things that try to keep up with Chrome. Not having to deal with IE11 or obsolete Safari or some half-working toolkit-specific browsers is definitely worth paying for with a 100MB download.
Another thing we tried were a bunch of non-web-based alternatives. I tried to pick the most promising ones, and skip the obvious trash, but none of them were acceptable.
And it's no surprise really. Every Java-based GUI I've seen was a barely functioning disaster, and Qt-based GUIs were not much better.
Not to mention none of them really solve our problems. OK, so we don't bundle the browser, but is telling user to "install Java" or "install Qt" actually better than telling them to "install Chrome"?
And as I said before, we'd still need to somehow install the backend.
I don't think anything can really compete with Electron when it comes to cross-platform desktop apps.
The best Web based alternative would be either "just run in the user's browser" (Jupyter style) any of the "ask the user to install Chrome" solutions (Ferrum style). I think these could be turned into viable solutions with modest effort.
Judging only by the quality of GUI programs I've used, I suspect the best of the non-Web alternatives would be .NET. It comes preinstalled with Windows, which is otherwise the most painful system to target, and it can sort of work on other systems. As I was writing the series on a Mac, I never tried that, but I've seen others be somewhat successful with it.
Qt based solutions were mediocre at best, and Java based solutions were all an unmitigated disaster.
As I recommend Electron so strongly, what do I recommend using with it?
For the framework, you can't go wrong with Svelte, which is the leading 3rd generation framework. There's nothing too wrong with using React, which was the leading 2nd generation framework, but React is extremely limited by being based on web capabilities and thinking from the mid IE era, and has a big advantage that you're more likely to know it, but looking forward, Svelte is the way to go.
I don't think other frameworks really have much to offer that those two don't. I really wanted to try Imba 2 with the series, but Imba 2's tooling was really getting in the way of Electron, and I was able to fix some of these issues but not all, so I ended up dropping the idea (I definitely ought to PR those fixes). Maybe Imba will be the next Svelte, but it's not there now.
As for Electron, due to its origin in attaching browser frontend to node backend with some IPC duct tape, many of its architectural choices are really awkward, with many concerns being on the wrong side of the frontend/backend divide, or even worse split between both. Fortunately, there's a lively ecosystem of npm packages that deal with a lot of that awkwardness around things like managing window positions, saving user settings, and so on, and you should absolutely check if there's a package that solves your problem instead of forcing yourself to use plain Electron alone.
And that concludes everything I wanted to say about Electron. In the final 100th episode of the series, I'll look back at what it was like to write a 100-episode daily blog post series.