I feel like I should edit this article and clarify a few things since someone posted this article on Hacker News, and it appears it has received over 440 comments. This means it has left the typical reader base of this blog (four and a half people). This whole article was written because I was trying to write a companion program to one of my kernel utilities. It’s not meant to be used by more than a few people (no need for excessive accessibility options). I will also use a custom code virtualizer/obfuscator on it, hence the requirement for native code and full control over the compiler toolchain (that’s why Embarcadero’s C++Builder is not mentioned). I think I somehow accidentally managed to write a cool clickbait article because if you take a single one of those requirements below out, at least one of those libraries will fit you perfectly.
For the past few days, I have been trying to find a library that would allow me to write programs with a GUI in C++. My requirements were pretty straightforward:
Only Windows support required
Commercial use allowed
Easy styling, including dark mode
The result should be a single .exe file with no or minimal dependencies and a size of less than 40MB
Writing the GUI part of the program should not take more time than the actual functionality
WinUI 3
At first glance, it looks like an excellent choice. It allows you to use modern Windows components while also letting you customize the styling colors. For design, you can use XAML, which is super easy to grasp, or you can just use the Visual Studio designer directly.
screenshot
(WinUI 3 controls gallery)
Problem: Shipping the app in unpackaged form is not well supported. Most of the time when I have tried moving the app to a VM or a different computer, it fails to launch due to some obscure dependencies missing. To make it worse, you need to supply a bunch of .dll files that handle the WinUI functionality. There is no way to have a single portable .exe file. Using packaged form usually works without any issues, but they are installed as AppX packages which brings many issues on its own (especially if you need access to all Win32 APIs).
Win32 / MFC / small libraries wrapping Win32
I need high portability, so it would make sense to use the OS’s native rendering. Such a program could be a single .exe file (given that we statically link MFC) and would also be super small (just a few kilobytes). I could also use a more minimal library that someone has already written, which means it would be really easy to get from concept to working app fast.
screenshot
(Basic Win32 form)
Problem: It is extremely hard to stylize native Win32 controls. It would require me to write a custom paint function for every single control, which would take so much time I could raise a family in the meantime. There is a “hidden” dark mode for Win32 controls used by Windows File Explorer that you can activate, but it covers only some of the controls and still doesn’t look good.
Qt
This library is the holy grail of C++ GUI. While it’s quite complex, it offers easy styling with Qt Style Sheets, which use a language similar to CSS.
screenshot
(OBS studio is using Qt and custom stylesheets)
Problem: When linking dynamically, there are a myriad of different .dlls required to run the app, totaling over 40MB. You can statically link Qt into your program, which will drastically reduce the size (since the unused parts are removed), but then you must either make it open-source or distribute object files for recompilation due to Qt’s LGPL license. Alternatively, you can buy a commercial license for several thousand dollars.
wxWidgets
Quite an easy-to-learn library with the option to use wxFormBuilder. It has a more permissive license than Qt and can be statically linked into a 3MB executable.
screenshot
(wxWidgets with experimental Windows dark mode option enabled)
Problem: On Windows, this library uses native Win32 components and offers no styling options (since we cannot easily overwrite the paint functions, it’s even worse than using Win32/MFC directly). It supports applying Windows File Explorer dark controls, but again, they kinda suck.