The easy decision to move from Electron to Qt at Lumina

At Lumina[1] (the statup I work), we switched our UI stack from Electron to Qt. Both are extremely popular and mature technologies, both had their pros and cons. But we ended up migrating by the end of 2021. I think the story is interesting and worth sharing. Hence this post.

For some context, Lumina sells webcams and provides a software for post-processing and image tuning. Early PoC software was MacOS only and written in Electron[2] and bridged to C++ for low level accss. This works quite well as we are able to leverage experiences from our web team. The native software team just have to deal with image processing and camera control. Crossing the JS <-> C++ bridge is easy-ish but prone to error. We had wrapper issues from time to time.

Then we had to face reality. We had to support Windows. Getting our code to link against and loaded by electron is a nightmare. Electron is really Chromium in disguise. And web browsers are more designed as a single piece of software, not a library to be incorporated into somewhere else. We fought linker issues for weeks without real progress. The fact that our build system was Makefile doesn't help either - MSVC's flags are alien to our UNIX-centric team. Finally at the time, our web team was busy pushing more marketing features to our website. Yet we promised a Windows version soon. Something has to be done.

Electron has it's own issues too. Displaying camera capture on Electron is CPU intensive - we measured 100% of a core on a MacBook for a 720p stream. Updating UI elements dynamically is also costly. Likeky updating CSS from JS causes the engine to re-evaulate a high portion of the layout tree. We also used Redox Epic as the UI code paradigm. It works, but our native team is not familiar with it. Causing communication issues.

We looked into other applications in the market - Qt seems to be popular. I also had some experices with Qt(4) before. Qt is native to C++. Linking our code against it can't be hard. The QML language is easy to use - All that is to say, Qt looks like our way out!

The initial UI mock in QML wasn't hard at all. After a few weeks we start to find Qt to be much better then Electron. It's an 100% improvment:

  • 50MB(Qt) vs 120MB(Electron) memory usage just for UI
  • Faster startup time
  • 10% CPU vs 100% CPU for 720p camera capture
  • Easy binding between C++ and QML
  • Sane CMake integration
  • No more messing with Makefile and Yarn at the same time

Qt is much lighter weight, easier to program and build. The only hurdle is LGPL. But it's easy to comply with it. How easy it is to program? Take exposing C++ variables and functions to QML as example. It's just a few lines of code. Q_READWRITE_PROPERTY is our macro to reduce mechanical work, to do signal and get/setter declarations for us.

class AppInstance : public QObject {
    Q_OBJECT
public:
    Q_READWRITE_PROPERTY(QString, myProperty, MyProperty)
    Q_INVOKABLE void myFunction(const QString& arg1, int arg2);
};

Then the function and variable can be accessed from QML. Heck, Qt parses the parameter type and checks it for us at runtime:

...
Text {
    text: AppInstance.myProperty
    onTextChanged: AppInstance.myFunction("hello", 123)
}

With Electron and Node Native Modules.. Man it is complicated. Just look at all the type checking and error handling boilerplate code. It's not fun.

void myFunction(const Nan::FunctionCallbackInfo<v8::Value>& info) {
    if (info.Length() != 2) {
        Nan::ThrowTypeError("Arity mismatch");
        return;
    }
    if (!info[0]->IsString()) {
        Nan::ThrowTypeError("Argument must be a string");
        return;
    }
    if (!info[2]->IsNumber()) {
        Nan::ThrowTypeError("Argument must be a number");
        return;
    }
    ...
}

How about productivity? Electron is more well known and supported, right? Easier talent sorcing? Kinda, but Qt has one of the best document[3] I've ever read. It allows our native team to get started quick. QML is IMO, a better version of Vue + HTML - QML is declarative and reusable. We also are no longer bounded to web team capasity for UI development. Designers can directly pass the UI mock to our native team. Reducing communication overhead.

Other advantages of Qt includes:

  • Type checking for native code
  • Massive 1st party utility libraries (IO/network/image/audio ..)
  • Single process model
  • Easy integration of low-level code with UI
  • QML enables reusable complex UI components across the application

And downsides (minuscule compared to the benefits):

  • No global style sheet
  • Media Foundation only on Windows
  • No built-in flex container
  • Component size can be finicky at times

Moving to Qt is likely the best decision I made for the project. Faster, lighter, easier. No chance I go back to Electron for applications that need anything more then just HTTP calls and basic IO. Heck, why even bother with Electron?

Author's profile. Photo taken in VRChat by my friend Tast+
Martin Chang
Systems software, HPC, GPGPU and AI. I mostly write stupid C++ code. Sometimes does AI research. Chronic VRChat addict

I run TLGS, a major search engine on Gemini. Used by Buran by default.


  • marty1885 \at protonmail.com
  • Matrix: @clehaxze:matrix.clehaxze.tw
  • Jami: a72b62ac04a958ca57739247aa1ed4fe0d11d2df