
Building a fast Electron app with Rust - hellerve
https://keminglabs.com/blog/building-a-fast-electron-app-with-rust/
======
actf
I really like where the author went with this. Everytime I read something like
this though I can't help but think how we as developers really need a better
low level, UI framework for cross platform applications. What the author has
done here is a cool idea, but ultimately this still feels flawed, and like
it's a workaround to the difficulties of writing a cross platform UI.
Everytime I read something like this I can't help but think about how great a
low level, cross platform C (or C ABI) library would be (think something like
libuv but for UIs). Such a library would abstract away the OS specific system
calls of the UI while still providing the ability to easily do things like: *
Create a window * Draw to the screen * Declaratively (i.e. html like) add UI
widgets to a scene * Apply CSS like styling (like QML, JavaFX, or XAML) * Use
native file dialogs, menus, notifications, etc * Statically link as a single
dependency

I don't even think something like this necessarily needs to provide native UI
elements, rather it just needs to be a more performant, easier to use,
smaller, version of electron that could easily be used from any language. It
needs to provide common UI elements like buttons, textboxes, divs, grid
layouts, etc, but judging by the popularity of electron - I don't think those
necessarily need to use native elements.

Qt is close to this, but it feels heavyweight and in my opinion its biggest
flaw is that it's difficult to link to an application and setup a development
environment for. Tk is kind of like this, but way too limited. JavaFX is a
really good example, and would be perfect if it wasn't Java only (same with
WPF but it's C# only). Right now the closest attempt to something like this
that I know of is
[https://github.com/andlabs/libui](https://github.com/andlabs/libui)

I think libui could even be a starting point for such a library, but the
library I'm thinking of would need some type of declarative UI support (i.e.
html like, maybe even support for a subset of html), built in support for
styling, and less of a focus on using native widgets. I really wish somebody
would build something like this.

~~~
ninkendo
Am I the only one with the opposite opinion?

I don't think cross-platform UI toolkits should exist, period. Your cross
platform code should live underneath the UI layer, and you should write a
custom UI for each platform you're bringing your logic to.

Mac apps should look and feel like mac apps, windows apps should look and feel
like windows apps, etc.

Trying to abstract away all these platform differences either nets you a
lowest common denominator that doesn't feel at home on any platform, or is so
complicated to develop for that you end up doing more work in the end (and
still isn't as good as writing native UI's for each platform.)

~~~
fenwick67
I hear this preached all the time but I honestly don't believe it.

Few third-party applications I use on my Windows computer have a native (or
native-looking) UI. Blender, Photoshop, text editors/IDEs, DAWs, video editing
software, even web browsers... The only real exception is the file dialog and
the window frames.

If they went to match the native UI they would dilute their brand at best and
lose usability at worst.

~~~
mcbits
One thing I can do in almost every Windows application is press Alt, or Alt+F,
and use the arrow keys to navigate the menus. This has been broken forever in
Electron's menu. It's my biggest complaint, even above RAM usage now that I
have enough RAM. I guess the Electron devs can take that as a compliment if
they want to, but it still gives me a "damn you Electron" moment every few
days.

I think it's the sum of those little inconsistencies that bug people about
cross-platform apps. On the other hand, people now spend so much time in the
browser that a browser-based desktop application can probably feel more
natural than a native UI if done right.

------
jayflux
> Given this goal, you might be surprised to learn that Finda is built with
> Electron, a framework that’s often decried for being the opposite of fast.

I thought the criticism was more about its memory usage, not that it wasn’t
fast.

~~~
JepZ
In fact, there are many downsides performance wise when you think about
electron:

\- it is as slow as any other web rendering engine

\- it uses as much memory as any other browser

\- you have huge binaries

The key benefit of electron is that you can easily build cross-platform apps
which run on every notable platform. Many of the _general_ weaknesses of
electron can be eliminated by building a Progressive Web App, but that doesn't
solve the performance challenges that come with building a web app.

Performance wise web apps are very slow when compared to C/C++/Rust/Go. E.g.
for a C program, a single millisecond itself is a long time. For web-apps you
struggle to get everything in a 16ms window to not break your 60fps
experience.

But the point is that while web apps are in fact much slower, they can be fast
_enough_. And if you have a technology that is very platform independent and
you can built good experiences with it, then you probably find some nice use-
cases.

~~~
afranchuk
>The key benefit of electron is that you can easily build cross-platform apps
which run on every notable platform.

I've been a bit confused about the draw of this feature. I understand that
there are a lot of JavaScript developers out there, and things like Electron
allow them to use their JavaScript knowledge to make applications on many
platforms. But there are now a large number of GUI libraries (GUI being a
typical obstacle for cross-platform support) that can target all these
platforms (and sometimes more) as well. GTK+, Qt, and WxWidgets name a few.
And they have bindings across many languages! Of course, to make something
that's completely custom-looking using these libraries may be more of a hassle
than an html/css document.

Maybe Electron's popularity _is_ primarily driven simply by the high numbers
of JavaScript programmers out there.

I guess it's like you pointed out: if you can get it to be fast _enough_, it's
acceptable. Kind of similar to interpreted vs compiled languages.

~~~
JepZ
The problem with Qt, GTK, etc. is that you can't use them on websites[1].
Meanwhile you can build most applications as websites, which don't require any
installation and are available everywhere and instantly.

I am a Linux desktop user myself, so I have some sympathy for Qt, GTK and
software distribution via package managers. Nevertheless, as a developer I
like the web better, as that is a platform which allows me to easily
distribute my applications to anybody on any platform within seconds.

Performance on the other hand is a topic by itself. The problem I see with web
applications here, is that it is much easier to create a bad performing
program with web technology than with compiled languages and toolkits. But
that is something you can learn and if you create some performance critical
software, easy distribution might not be your top priority.

[1]: I mean I have seen GTK rendered on a html canvas some years ago, but as
far as I know nobody actually uses that kind of tech.

~~~
afranchuk
For that matter, I remember seeing some Qt thing for targeting websites too.
But I agree with your points. Lately I've had to write UIs that actually need
decent performance (client-side custom rendering and data processing
requirements), so my preferences are biased.

------
lynaghk
Author here.

For more background on product development about Finda, there are notes on my
personal website here:
[https://kevinlynagh.com/datatron/](https://kevinlynagh.com/datatron/)

I started this as a UI research project to try and replace OS X Finder with a
keyboard-only UI. A strong inspiration was the Helm Emacs package.

My initial prototype was in ClojureScript/Electron, and I was exploring far
more features like inline preview, and a command/argument (verb/noun?) builder
system.

However, after showing my prototype to a few friends, they were all much more
interested in the fast search and window switching capabilities, so I decided
to cut scope, focus the project on those features, and get something out the
door.

This is my first Rust project, and I've been thrilled with the language and
that community in terms of great libraries, documentation, and their
willingness to help beginners like myself.

p.s. Sorry I'm late to the party, I pushed this blog post online immediately
before going to sleep for the night =P

~~~
vkjv
Just wanted to say "hi" and that this is a great read! If you are interested,
there is a Neon slack where some of us hang out. For example, you might be
interested in neon-serde which could clean-up some of the argument parsing and
match logic.

[https://crates.io/crates/neon-serde](https://crates.io/crates/neon-serde)

------
matthewmacleod
I think it’s cool that people are playing around with this sort of thing.

The truth is, though, I don’t understand why this architecture is attractive
in this case. This is essentially a thin front-end UI on top of a fast cross-
platform backend. That’s a great structure - but why not make the UI _native_
for each platform?

Calling into a Rust backend from Swift, or from whatever UI framework you use
on Linux or Windows, is going to be just as easy as with Neon. At the moment,
you are including _vast_ amounts of code and using a large amount of memory to
display a very small amount of text on-screen. It seems very inefficient for
such an otherwise elegant application!

~~~
cornholio
Because writing, testing and deploying on each of those platforms will
increase your effort from X to N*X.

I don't think Electron a good match for this project, which while fast during
use, probably has horrendous startup times and memory usage. But I can
certainly understand the sentiment pushing developers into Electron and
driving them to avoid multiple native applications like the plague. I have
developed and deployed custom Eclipse environments that supported Windows and
Linux, with a mix of Java and C/C++. It costed me years out of my life.

~~~
Aaargh20318
> Because writing, testing and deploying on each of those platforms will
> increase your effort from X to N*X.

No, it won't. Building any non-trivial UI in HTML takes orders of magnitude
more effort and time than building it in a UI toolkit that was actually
designed to build user interfaces in.

~~~
Klathmon
That is absolutely false in my experience.

I can put together a full HTML/CSS/JS UI for a screen in hours where it will
take me days to do it on Android or iOS alone, ignoring the fact that I'd have
to make sure it's responsive on all those platforms anyway (because tablets),
then still build it for windows, linux, mac, and sometimes a web version
anyway.

~~~
Aaargh20318
> I can put together a full HTML/CSS/JS UI for a screen in hours

Hours for a single screen ? Exactly what I'm talking about. The fact you think
that's quick is worrying.

~~~
Klathmon
You are the second person to say this, what are you doing that's faster?

I'm talking from start-to-finish creating the UI, wiring into business-logic,
handling UI state, making it fully responsive, etc...

I've used WPF, QT, some old java swing stuff, and the Android studio layout
editor, and none of them are a fraction as fast and capable as a well setup
react web application (which to be fair, took a good chunk of time to setup).

------
tybit
I noticed the atom team are trying something similar with an experiment called
X-ray [https://github.com/atom/xray](https://github.com/atom/xray)

It will be nice if this becomes a thing, I think it’s more likely that
electron apps become significantly more performant than that everyone starts
rewriting their apps in QT, for better or worse.

~~~
tonyedgecombe
POC?

~~~
Mononokay
I'd imagine "Proof of Concept."

------
krzat
I've been playing with Flutter recently and their approach may dominate UI
toolkits in the future.

They took low level rendering API from Chrome (Skia) and build simple but fast
layout engine around that. Already works pretty well on mobile and there are
some experiments on desktops:
[https://github.com/rxlabz/flutter_desktop_markdown_reader](https://github.com/rxlabz/flutter_desktop_markdown_reader)

Rust people could maybe do the same with Webrender from servo.

~~~
mnem
The downside of custom rendering engines is that they’re rarely as efficient
as the standard platform affair. While that’s less impactful on desktop, it
can be a killer for batteries on mobile devices and laptops.

~~~
pcwalton
That's not true. There's no magic sauce that the platform vector graphics
library has: it's a userspace library like any other (well, except for GDI,
but nobody wants to use that anymore). It's absolutely possible to improve
upon it.

~~~
mnem
Generally platforms providers optimise graphics highly for their own platform.
A generic cross platform library rarely invests similar effort for every
platform it can run on. The usually applies more to mobile however - most
desktops require even the platform providers implementation to be somewhat
generic.

The other part of the inefficiency is more to do with what the cross platform
engine is internally guaranteeing vs what the platform providers will
guarantee. For example, let’s say skia here always runs at 60fps. Great, and a
lovely user experience - but does it then respect low power mode in iOS or
Android, or does it just continue at 60fps eating away through battery power
because it’s geared to the common case of all platforms?

I’d love this to work, but years of the reality of using cross platform
renders has made me quite skeptical of their ultimate benefit to the user.
They’re great for developers though - but that’s the wrong way round for
convenience usually, I think.

------
alfonsodev
> The architectural tl;dr is that Electron is used as a user interface layer,
> with a Rust binary handling everything else.

Interesting, but the major complaint about electron that usually pops in HN is
about memory consumption. Is it that avoided in this case?

~~~
tarruda
If the app uses no Javascript UI frameworks, and completely maintains all
UI/DOM state in Rust code, it might be possible to significantly reduce memory
usage when compared to typical Javascript apps.

Keep in mind that "electron-quick-start" (basically an empty Electron app)
uses 40 MiB on Linux, so anything with a slightly complex UI would probably
not use less than 50 MiB, regardless of the "backend language".

~~~
AnIdiotOnTheNet
To put this in perspective, all of Windows 95 fit in about 50MiB on disk and
ran in something like 8MB.

------
dreta
You can't seriously justify introducing massive library into your code just to
display some text, and use a few native calls. If it works for you, that's
great, but if anybody needs an example of why the software you use is so
terrible these days, even though we had huge leaps in technology, look no
further.

~~~
tarruda
If all this app does is display text, it would have been simpler to embed a
rich terminal emulator widget and implement the backend as a Rust program with
terminal UI

~~~
derimagia
It has a GUI...

------
hardwaresofton
I wonder how this approach will combine/contrast with compiling rust to wasm
directly -- I'm under the impression that the benefits would be similar.

I absolutely believe building electron apps is the future -- why would you
struggle with the M*N effort of building different UIs when you can get
comfortable with a paradigm that you already know that works relatively
predictably across OSes and is constantly being improved (HTML+CSS).

Unfortunately, one of the big problems left to get tackled (I think?) is the
lack of native system accessiblity features that are more advanced than what
the web can/does offer.

So excited to see this idea getting attention -- I really want to work on a
cross-platform app with neon + rust in the future, and see if we can finally
get past the gripe of memory usage for electron apps so that people can stop
bashing them.

~~~
lynaghk
Author here.

I'm compiling Rust to WASM on another project, so I can address this question.
I haven't studied relative perf, so can't make any claims there.

But for this application your guess is correct: It's iterop. It's easier to go
with Rust via Neon rather than WASM because Finda needs to:

\+ Walk the filesystem for file results

\+ Call OS X CoreGraphics APIs to list windows

\+ Run a websocket server to collect results from browsers and VSCode

All of this requires leaving the browser sandbox, and so can't be done in
WASM.

------
minus7
Is it really so hard to write a native GUI for three OSes if you must?

~~~
allover
> Is it really so hard to write a native GUI for three OSes if you must?

Yes. What makes you think otherwise?

~~~
jsjohnst
Here’s three reasons (more are certainly available):

[https://github.com/rust-gnome/gtk](https://github.com/rust-gnome/gtk)

[https://github.com/KISS-UI/kiss-ui/](https://github.com/KISS-UI/kiss-ui/)

[https://github.com/PistonDevelopers/conrod](https://github.com/PistonDevelopers/conrod)

~~~
Thaxll
Real repo:
[https://gitlab.gnome.org/GNOME/gtk](https://gitlab.gnome.org/GNOME/gtk)

~~~
jsjohnst
How is that a “real repo” and mine aren’t? The article this thread is about is
written in Rust for the majority of the app. I linked to three cross-platform
UI bindings/libraries for Rust that could’ve fairly quickly provided the same
UI that the Electron portion provided. I get it some prefer Electron and
that’s ok, but to say that cross-platform coding is inherently difficult
otherwise is a bit of a stretch to me.

------
cheez
> 1) I want the option to port Finda to Windows and (I can’t believe I’m
> saying this) Linux, since beta testers asked if they could buy a version for
> their respective platforms.

Anyone else reading this: Linux support is required for any tech-related
thing. Many times I have sold licenses into a single person using Linux who
then has their company come back to buy 10s or 100s of licenses.

~~~
AnIdiotOnTheNet
> Anyone else reading this: Linux support is required for any tech-related
> thing.

Which is why pretty much everywhere I've ever worked has run off a combination
of Exchange, Office, Sharepoint, Windows file servers, and a plethora of
legacy Windows-only crapware.

If you work with nothing but webdevs all day though, I could see how you'd get
the impression that Linux support for GUI apps is something anyone cares
about.

------
LeoNatan25
Just to show how well this works, the attached GIF on that site uses OS X
Mavericks, now 5 years old.

I also like how they only considered one real alternative, which is "XCode"
(incorrectly capitalized). What about Xamarin / Mono? What about qt? With
those, they don't even need to upgrade their outdated OS. Instead, they chose
the worst of all worlds, both development and user.

The state of development in 2018 is ridiculous.

~~~
kiriakasis
It is written in the article that the author had experiences with electron.

> they chose the worst of all worlds, both development and user.

to me this looks needlessly inflammatory, the whole point of the post is "hey,
electron has a bad name for both lags and high memory and CPU usage, but with
rust i was able to get its benefits without its common drawbacks". If you
think this is so ridiculous i think some more explanations are needed.

------
Humphrey
I wonder if there is a use-case for a simplified lightweight edition of
Electron that uses the system webviews instead of Chromium.

Obviously this would be much less capable, require cross platform testing, and
limit node usage. But for a project like this that barely does anything fancy
in the front-end, it would solve the size and memory issues.

~~~
roryisok
I've often wondered this. You could write a set of generic webview based apps
(say, Windows 10 and MacOS to start) and a small js library that would allow
cross platform access to low level apis, even just a few at first like file
dialogs. React native is sort of like this.

------
charlieflowers
I thought this was intriguing, so I installed it.

Doesn't work at all for me. Running finda shows the instruction screen. Try to
use it by typing, and the window goes completely white.

I can use ctrl-\ to bring the white window up and down, but nothing else
works.

I had to find the launchd process in Activity Monitor to kill it so I could
uninstall.

~~~
lynaghk
Author here. Sorry that it's giving you a hard time. Can you say what OS X
version you're running or provide any other details so I can try and
reproduce/fix? (You can email me privately at finda@keminglabs.com)

I tested with a dozen folks before releasing and this issue never came up.

~~~
lynaghk
Haven't heard from OP, but another person emailed me and the issue is likely
because Finda relies on AVX2 CPU instructions for fast search. These
instructions were introduced in 2012, so it's likely the OP was running on
older hardware.

I'll add CPU detection to a future version of Finda so that it can fallback to
slower, non-vectorized instructions.

------
tracker1
I think it's wild that the browser has become the UI layer in so many
applications... CSS + HTML simply make things more consistent in a way that no
other toolkit ever has. On the flip side, it's sad that every app now packages
the entire jungle (so to speak).

I know that this is what Adobe Air was supposed to be, and part of me would
love to see something akin to Chrome's autoupdate mechanisms for an Air-like
platform around Electron's base that could be shared. That doesn't get around
performance issues, but would at least mean some reduction.

I think it's a great option to have, but still concerning in some ways. I also
think that React-Native will probably grow to be easier to create more native-
like cross platform apps over time. Definitely interesting times.

------
snarfy
Whenever I find myself wanting to build an app that is
electron/chromium/webkit frontend + C++/C#/Rust/Go backend I can never justify
it over building a web app + web api instead. If you want to run it locally
there is a one line docker command to do it.

~~~
roryisok
Doesn't the user need to have docker installed to run that one line? That's
kind of a big prerequisite

~~~
snarfy
Since it's a web app, they could go to my hosted site if they can't install it
locally. That wouldn't work for the OPs app but it would work for most. The
point being there has to be a better way than frankensteining the browser.

~~~
roryisok
It depends on what you consider "better". I'd much rather install an electron
app than mount and run a docker container, and I say that as a developer who
uses docker every single day.

------
mamcx
This is only possible because the browser on desktops is "fast".

I try the same idea with Android/iOS. In iOS, all fly, but man... android is
super-slow.

I can't believe it myself, so I downloaded several demos of html-based apps
and the results hold.

I totally will kill for a webview-like control on android that I could
reliable use and be almost 80% as fast as on iOS..

Now I implementing the UI on both, and seriously is harder than I expected...
Never imagine the Apis were that bad...

------
swsieber
OK. Dream time. I'd love to build a cross platform app / ui toolkit with
support for pluggable backends. The first two would probably ncurses and
electron if I were building it. (I'd do it rust for its excellent Web assembly
story and perfeomance.)

~~~
roryisok
You have my permission, fire away

------
tixocloud
Thanks for sharing this.

I’ve been dabbling with Electron to build a data analysis tool app but have
been slightly concerned about speed. I am glad to hear how quick it’s running
for you and getting ideas on how I can make my app faster.

Thanks!

------
BlackLotus89
Interesting that nobody seems to talk about the software itself and maybe it's
alternatives.

I for once welcome the concept of something like Finda and am looking for
alternatives for me.

> Finda finds things — windows, browser tabs, code editor buffers, browser
> history, apps, files, etc.

Finda looks and acts like a normal launcher. The concept isn't new, but fast
good launchers are rare. When we look at the Finda-Page (I didn't download the
demo since I don't use Mac OS) we can conjecture how it works and there are a
few things that bother me.

It seems to always run in the background and listen for inputs. It's cross
platform so it will probably have it's own file indexer.

This all seems to add up to a rather large memory consumption.

Anyway right now I'm still using the dmenu [1] launcher and am looking at many
alternatives, most of which haven't been updated in some time.

First the ones that haven't been updated in some time

dmenu2 [2], interrobang [3], and lighthouse [4].

All nice launcher, but here comes my current favourite rofi [5]. Not only is
it an active project, but it defines itself as window switcher and launcher
(so what finda kinda does). Combined with it's extendable nature it seems to
be a solid launcher. Bookmark functionality is for instance given with the
buku [6] integration. But I'm still looking for the best solution. Here is the
feature list I'm looking for: program launcher, simple calculator (through bc
or python), file locator (maybe through locate), bookmark manager (firefox
preferably). Other things like quick (online) search, clipboard management or
the whole slew of other features provided Finda and panther and whatnot would
just be extra. Does anyone of you have a nice lightweight solution?

[1] [https://github.com/stilvoid/dmenu](https://github.com/stilvoid/dmenu)

[2] [https://github.com/muff1nman/dmenu2](https://github.com/muff1nman/dmenu2)

[3]
[https://github.com/TrilbyWhite/interrobang](https://github.com/TrilbyWhite/interrobang)

[4]
[https://github.com/emgram769/lighthouse](https://github.com/emgram769/lighthouse)

[5]
[https://github.com/DaveDavenport/rofi](https://github.com/DaveDavenport/rofi)

[6] [https://github.com/jarun/Buku/](https://github.com/jarun/Buku/)

\- bl

~~~
lynaghk
Author here, and happy that you're interested in the software itself rather
than the implementation =)

I'll probably write a detailed post about file indexing, since it's pretty
interesting from a technical standpoint.

I looked into spotlight (via `mdfind`) but it was too slow and I wanted to
port to Windows/Linux later, so your speculation is correct: Finda has its own
file walking and indexing mechanism.

It walks a user-configurable set of directories, but not in the background ---
it's actually done every time you open Finda, so you only pay the CPU cost
when you are actually using the program.

The index is stored in memory, and size is proportional to the number of
files/folders walked. However, Finda does respect .gitignore files, so you can
exclude things you don't want to show up in the search results (or consume
memory).

~~~
BlackLotus89
Hey thx for the detailed answer. Thought that it might work like this.

How hard would it be to replace the electron frontend with something else? I
was thinking about replacing it with some of my solutions I already use, but
with your rust backend.

------
angel_j
what is require('Native')?

------
pughmans
I hate javascript so this might be good.

------
holydude
The other problem is that most electron apps are incredibly big. I do not want
to download 150mb single purpose apps. The memory hog is not the only it's
also the battery drain most electron apps suffer from.

If you compare Finda to something like voidtool's Everything it's night and
day.

~~~
KeitIG
I don’t understand the size argument. Disk space is super cheap today.
Facebook’s Android app is 350MB and not a lot of people really care, on
Desktop, 150MB is nothing.

Plus it satisfies the “all libs/dependencies in one app”, which is exactly
what macOS’s .app, Linux’s Snaps and AppImage, or more generally all
Android/iPhone apps are doing.

I agree with the RAM/power things too, but these issues come from web pages in
general, not Electron itself.

~~~
LeoNatan25
A clean "hello world" Electron excrement takes 200+ MB in RAM. How is that an
"issue from web pages" exactly?

~~~
tarruda
Where did you get this information? I just tested "electron-quick-start" on
Linux and all 3 processes use 40 MiB together

~~~
wander_homer
Here on my systems (Ubuntu, Gentoo) electron-quick-start leads to ~90 MB more
memory usage and it spawns 4 processes which use 110MB, 74MB, 74MB and 44MB of
resident memory. So obviously quite some memory is shared between those and
probably other processes on my system, but nevertheless the resulting memory
consumption is far above 40 MB.

~~~
tarruda
I used gnome-system-monitor to check memory usage, which doesn't include the
memory used by the executable image itself, and which I believe is more than
60 MiB.

Theoretically this memory could be shared by all electron applications running
in a single machine. In practice every Electron app bundles its own runtime.

------
tzahola
Cool! Still waiting for “building an electron app that uses less than 200
mbyte of RAM” though.

