This is a good overview of some of the options, but the author’s specific requirements push it in a specific direction that eliminates a lot of options.
Specifically, the requirement for completely custom GUI styling without writing his own render functions means it’s really a task of selecting easy, customizable GUI libraries rather than generic GUI work.
The requirements to be self-contained executables and under a 40MB limit also rule out a lot of options. The author admits that Qt could have met these requirements but the open-source licensing part wasn’t compatible with his goals and he didn’t want to pay for a license.
If you relax the requirements to tolerate some dependencies, allow larger download sizes, or to simply use built-in Windows GUI controls the situation is very different.
For writing a lightweight, completely custom GUI with no external dependencies and permissive licensing I could have guessed ImGui would be the answer before I started reading.
If instead of insisting on custom UI styling the author just used the system UI, they could probably build a pretty straightforward Windows application. It’s the scourge of “brand identity” that has people thinking graphical applications are hard.
Same on the Mac: If you want to build a Mac application, your best bet will be AppKit or SwiftUI and using system controls. And when the OS updates your application will either update with it, or need only minor tweaks and a rebuild to look good.
My experience with SwiftUI on the Mac is that it still needs a lot of work. Documentation is poor. Performance can be bad if you do things in a straightforward way. Supporting older versions of the OS is quite painful etc.
I recently built a small app using SwiftUI. It was my first, and pretty simple.
The documentation was absolutely maddening.. Half the time the Apple docs referred to a previous version. “Do this thing in XCode” often included screenshots of UIs that don’t exist in the current version of XCode. Examples I found on Stackoverflow or random blogs were usually no longer applicable.
It felt like magic when it worked, all those VStack HStack nestings, but the annoyance of finding my way there made me seriously doubt whether I’d build a big app with SwifUI, especially if I wasn’t working alone.
Thanks for the follow-up. These types of anec-data are the best part of HN.
I know the feeling from Qt. I think Gtk and many other GUI toolkits use the equivalent of VStack and HStack to make resizable GUIs. Some GUI toolkits try to avoid this problem by using a grid layout, but it is more rare.EDIT
From your experience, what GUI toolkit would you prefer? And, it would help to know what is your target UI platform.I don’t have much app experience, I’m mostly a back-end guy trying to build some prototypes and (hopefully) one product.
I’m not in a position to give anyone advice, but I’d love to find SwiftUI but cross-platform and usable from anything other than XCode (well maybe not Ed…) and native GUI and a pony.
For my product I need to support Mac, Windows and eventually iOS/iPadOS. For prototypes iOS is enough. I don’t mind learning new languages for this, but ideally there would be some advantage in knowing the language itself. I’ve been looking at lots of frameworks over the past month.
The most tempting thing so far is Flutter, but I have nagging doubts: because it’s not native UI, I worry about that being a no-go for some large customer down the road, and also about alienating power users. I looked at React Native but it’s not very good for desktop yet as far as I could tell (and the demo app from the documentation doesn’t work, which is a bad sign). Which is too bad because I was impressed with Expo, if I just needed phones I’d probably use that. I looked at Avalonia but it has the opposite problem.
Today I’m looking at Tauri for the Nth time: at least I could improve my Rust, and it seems to have momentum. Doing the UI in a web view is kinda sad, though, after trying SwiftUI.
Just building multiple apps is not realistic, I’m a solo dev and want to get this to market in my lifetime, and it only makes sense if I have both Mac and Windows.
Very happy to hear recommendations from people who have done this!
If you really want native look and feel then really your only choice is to use the native toolkits.
I'm not convinced many users care that much about this though. They spend most of their day using apps that don't use native controls and I think they're all pretty used to it by now.
I prototyped a bunch of different desktop toolkits and I think that today Flutter is by far the most polished and mature. I've had overall a very positive experience using it for my music app:
https://plastaq.com/minimoon
The threat of Google canceling it is real though. I suppose if that happens I'll switch to Tauri or just give up on Windows and Android and do SwiftUI. My experiences with SwiftUI to this point have not been very positive though.
Kotlin Multiplatform might also be an option at some point but it doesn't seem that close today. Unfortunately it seems like none of the os vendors are making their desktop APIs a priority these days.
Thanks, I will have a look at that. Serendipitously, I'm in the market for a new music player!
Yeah the Google risk... seems like they came out strong in support of Flutter at their last dev conference, but at the same time it does _not_ look like they're using it for their main apps.
Please let me know if you have any feedback or suggestions for the player.
And yes I’d feel more confident in Flutter if Google was dogfooding it a lot more.
Without expressing an opinion on Flutter as such, it's worth remembering that Google is a big enough organisation that even -some- internal apps being built using it is quite a commitment, and it not having spread further internally could easily be a social or political rather than a technical issue.
I’ve had overall very positive experiences with Flutter. If I wasn’t concerned about Google’s long term commitment to it I’d use it for everything.
Did you do cross-platform and if so, did you use the same UI style for everything?
Today I was making a list of reasons/excuses for using Material Design on Mac… which I guess would make some people mad, but it might work for an enterprise product.
Yes cross platform and the same style. I don't think this matters much to users today. They're used to it.
That said I did do a fair bit of my own theming. The Flutter Material widgets are actually pretty customizable and I'm not a big fan of vanilla Material.
https://plastaq.com/minimoon
Yes. Two different things. The SwiftUI docs are mostly just listings of functions and not much explanation of how to use them.
Plus, half of the official examples are given to you as a full Xcode project that you must download and import
Documentation remains the number one reason I personally don't make Android apps and why electron/web apps are the way to go for most GUI apps these days.
Unfortunately it doesn’t seem like having good, bug free, modern and well documented desktop APIs is a priority for anyone anymore.
This indeed. Custom UI widgets for Windows apps are really not necessary most of the time, and fitting in with the system theme is all you ought to aim for, most of the time.
There are exceptions, for very rich dense UI, for UIs that need to be cross-platform, but if you're writing a Windows app, it should look and feel like a Windows app.
That’s not exceptional at all. That’s completely normal requirements that are probably in the majority.
Does Microsoft themselves build their apps this way?
Most applications would be fine with a button on Windows looking like a Windows button, a button on Mac looking like a Mac button, a button on Android looking like a Material Design button and a button on iPhone looking like a UIKit button.
You need consistency in the icons, layouts and concepts, but you don't need every widget to look exactly the same on every platform.
Right. I want your app to have consistency with the platform I’m using. Not between all platforms.
With the exception of games try to use the native GUI. It’s the best choice most of the time.
I'm not sure anyone could really answer this question considering how fast Microsoft's various silos pinball between UI conventions. All of them are (I would hope) based on various iterations of their own internal tooling, but looking from Windows 7 to 8, 10, and then 11, you get such stark differences in UI language that you feel like you're looking at competing products.
That being said, I would personally very much prefer apps that are built to mimic the system they are a part of. One of the worst sins of that one, IMO, being iTunes on Windows which has always been and continues to be a flaming dumpster fire for a number of reasons, but most especially it's UI. It is a Mac app that is parked in Windows. It looks like a Mac app, it operates like a Mac app, it's UI conventions are that of the Mac, with the one major difference being they stuffed the window controls in the window in an incredibly slapdash way to account for Windows not having the system bar.
But yeah, for any marketing people here, I have not once nor will I ever give a single molecule of a shit about your brand identity. Make your software good. Ideally make it mesh with the system it's in. I couldn't fucking care less what color everything is.
Even Microsoft struggles with that.
Only because they change the system theme every 45 minutes.
Seriously, someone needs to reign in their UI department. No more refreshes until you actually finish one.
Or if you’re making games. All games seem to cherish a unique look even starting from the game menu or title screen.
He should have used C++Builder. Native Windows widgets (so you get, eg, IME support) but it can theme them. And comes with dark themes!
Edit: and fully static linking. Might be a meg or so.
The blogger sounds like they put up a bunch of arbitrary constraints that in normal circumstances wouldn't even be issues.
In the process it's those arbitrary whimsical choices that reject the very obvious choices along with any happy path.
For example, it's baffling that there are already a few FLOSS forks of Qt out there, but the blogger failed to cover them. If the author likes Qt so much, those would supposedly be the obvious choices. But no.
Once again, you are left out of options if you go out of your way to avoid each and any option.
Isn't the issue with Qt exactly what the GPL intended?
In that case, any Qt fork would force him to also comply with the GPL, and supply the source code of his project.
LGPL. Which eliminates his requirement for a single executable. With LGPL you are only allowed to link dynamically.
The goal of this is so that end-users can modify or update Qt, the LGPL licensed component.
The LGPL is working as intended.
Yes. But the article states that they don’t care about that. They just want a single executable.
I never understood the need for a single executable on windows when folders, zip files, and 100% free installers exist if you don’t like zip files. Also nearly all of the gui kits he’s shooting down have ways to build custom components if that’s what you want to do.
No need for an installer when it's just one file you can run anywhere. And folders/zips are way too hard for the average user. Ask me how I know. My partner gave up an entire game platform because it was delivered as a .7z file they could not figure out.
But a .7z requires a custom expander, .zip is natively supported by windows, isn't it?
.7z recently got native support.
None of these help you if you are dealing with users that move executables for convenient access or think updating the sofware just involves dragging and dropping the new executable into the existing installation folder. Customer support had countless stories like that.
Then pay for a license or make the object files available to users who want to relink the app.
Not true at all. The LGPL does not specify anything about mode of linking or anything like that.
What the LGPL requires is that the end user be able to take the source code for the LGPL part, modify it, recompile it, and then replace the functionality in your binary provided by that part with their new part.
Obviously with dynamic linking this is almist trivial, the end user replaces the so or DLL and done.
With normal static linking, it's only a bit harder. If you ship alongside your binary a bundle of eg .o files and a script that links them together with a .a for the LGPL part for example, this is also compliant without revealing the source code to your non-lgpl part.
This is super clever, I love it! Does any software actually do this?
Yes. For instance some Cisco app on iOS that uses gstreamer (LGPL) does exactly this.
Do you need to ship it alongside or produce it on request or link to where they can fetch it? It's not like you need to ship source code alongside either for GPL binaries.
You might even be able to use partial linking (ld -r) to ship a single .o file instead of a bunch of them.
The linked post does mention that:
Cool!
Does this also mean that one could put most of the closed source part into a DLL, make a shell executable that is open source and statically link LGPL code into the latter? This then would allow modifications to the LGPL code to be put in just by having the closed source DLL.
CopperSpice is LGPL, not GPL.
It's not a problem.
Hmm. How could that be when it's based on Qt?
Qt is also available under the LGPL. There is no license advantage to using CopperSpice. I'm not sure what GP is referring to.
Some parts of Qt are GPL only.
True, but they are optional and are not the parts you need to create a GUI as per the requirements in the OP. I assume CopperSpice does not include these components.
Dear ImGui is for development/debug tools, not an UI for the end-user. It's great for small projects as long as you don't care about accessibility, or proper keyboard support, or adherence to standard UI conventions, or support for devices without GPUs, proper font rendering, etc. ...
It's also suited to games, where "non standard" UI is expected and part of the experience.
Most games don't use ImGUI, though. Like the parent commenter said, it's useful for debugging, but the actual in-game UI—HUD, inventory, map, etc—is usually rendered by yet another middleware framework like Scaleform, or something that the engine provides (Unreal or Unity).
Nuklear is sometimes used. Anyhow, I do know of some game engines created and used by a (very large) game studio that uses ImGUI. I won't say anything else though :)
It often isn't a secret: https://github.com/ocornut/imgui/wiki/Software-using-dear-im...
This is true. There is a reason why Scaleform made its way to become a popular gaming UI framework even though many of its weakness. The most important focus in game UI framework should be on tools and pipelines for artists/designers and this is usually not up to engineering decisions. I won't say that using ImGUI for game is impossible, but there might be lots of tooling works ahead for production game development.
imgui offers incredible development speed. And I've used it many times with great success. It's unorthodox yes (and there's a long-open bug I won't talk about again) but it's dear to my heart. It's like MFC on steroids: You don't have to leave C++.
But yeah at least a few of those caveats remain. Although keyboard navigation and font rendering have quite a bit of support.
Due to what reasons does imgui offer incredible development speed?
Because adding a text is just a imgui::text("abc") function call. And a button is just an if(imgui::button("click me")) do_something() statement. There is no other language involved, no markup, no gui editor. Just direct code and highly hackable to make this extend to unexpected lengths.
Thanks, got it.
I currently see two international keyboard issues:
- French Keyboard and Backend SDL2 - Several keys are not checkable with IsKeyDown
- Wrong ImGuiKey keydown indexes reported from Win32 backend for some keys when using UK keyboard with UK keyboard layout
There are also 2 issues with IME:
- Marked Text / SDL_TEXTEDITING Event / IME Composition support
- Backspace handling by text widget in default Windows IME environment.
Excellent reply. I did not consider international keyboards when I writing my reply. And gaming companies are definitely targeting international markets in 2024!
ImHex uses it for the entire UI
And that's a dev/debug tool, just as explained by OP.
There is also furnace[0] and mmlgui[1]. Which are recently developed programs that people have been using to create chiptune music for retro video game consoles. Including being used by Yuzo Koshiro[2].
[0] https://github.com/tildearrow/furnace
[1] https://github.com/superctr/mmlgui
[2] https://x.com/yuzokoshiro/status/1800554520256360794
Agree. "Single executable" combined with "less than 40mb" is just looking for trouble for what the author is trying to do. If you want to do win32, go ahead and give up styling. Otherwise, make compromises. I think many of these are excellent choices chosen by many programs that I use, it's the author's stringent requirements and unrealistic expectations that is holding back.
This comment makes me feel like I live on a different planet.
In 1999, I built a completely custom Win32 GUI for a (brandable) chat application - that was the product the company I worked for was selling.
Pure C and C++. It was a 32-bit app, not 64 bits. And we felt bad for it being 250KB single executable (skin included in resource section) and not “150KB or less” as was our initial target. But making it accessible and fully skinnable/themable/l10n/i18n did add quite a bit which we hadn’t realized when thinking 150KB was realistic. But it’s not like we resorted to any crazy tricks; that was just the stripped linker output.
It was still a reasonable download at the dominant dial up internet at the time (28.8Kbps IIRC)
Sure, modern tools add a lot of cruft that you’d have to work hard to reduce, but 40MB. Oh man.
It is perfectly fine to build a 150KB or less executable today. But then OP decided they don't want to write paint functions for custom GUI and insist on finding a library to do so, I guess that's not what you did in 1999, right?
I actually used FLTK for the first iteration; The theming support it had at the time was not sufficient, though, and the i18n story non existent (that was before even 1.0, versions were still labeled by dates).
So, because pervasive theming/branding was a hard requirement, and i18n a softer one (every skin has to only support one locale), i had to abandon FLTK. But FLTK did spoil me by providing seamless flicker free double buffering out of the box, which I insisted on implementing in our gui.
For those of you who don’t remember - Win32 flickered badly on almost all screen updates, window resizes, etc — I think that was generally true of most apps until 2010 or so. FLTK was essentially the only GUI toolkit at the time (1999) that had no flicker out of the box.
Given that it’s windows, it might still run today, so it likely is still possible
Winamp comes to mind as a counter example.
IMO, every media player since Winamp 2.x has been largely a step _backwards_ in pretty much every metric one could put forth. It was light-weight, using minimal CPU & RAM. It was skinable. It was reliable. It had great plugin support. I don't recall it leaking memory, either. I basically had it set to auto run on login on my PC. I never closed it. Didn't need to. I had _only_ 32MB of RAM on that computer.
+1.
I still use Winamp, and essentially in its 2.x mode.
My app is around 500 KB (not megabytes) and it supports dark mode (see https://www.abareplace.com/). So this is definitely possible without using Electron or bloated GUI libraries.
If you’re on windows and want a “standard” guy, either use the .net GUI or Qt , if you want completely custom and willing to do the work use QML or ImGui (or variant like eGUI)
Which particular .NET Gui? There is a collection of them: MAUI, WPF, Blazor Hybrid, WinUI.
Microsoft have utterly screwed the pooch on getting their .NET GUI story straight.
WinUI 3 is the default for Windows-only applications
Nah, it is so bad, that on BUILD 2024, they have brought back first level status to WPF.
No one burned with WinRT history since Windows 8, is ever touching WinUI, unless they are Microsoft employees on WinDev, or companies with sunken costs trying to keep their products around.
Win UI 3 is the worst kind of improvement because there's arbitrary equivalence between WPF concepts and WinUI concepts, not a 1:1 equivalence. WPF as the mature stable model should be gospel; you don't re-write the gospel. Yet Microsoft feels they should re-write this gospel because... it aligns with the vision (???). Both use XAML, but the concept of DataContext is substantially changed, the concept of bindings is substantially changed, etc. Why make every XAML attribute ever-so-slightly different? Are those changes really an improvement? A lexical improvement? A performance improvement? Or just baggage and overhead to learn?
Compare Microsoft to OpenGL. Boromir says "one does not simply change the OpenGL API..." Microsoft does not have nor ever had OpenGL level of API with their UI frameworks. I guess you could say WPF is maturity in age only but doesn't represent conceptual maturity.
With the differences, you basically throw away all the knowledge of WPF to restart in WinUI, and with poor documentation. The documentation is there, i.e. the "what" but the docs should be primarily "the why and how"; how to map WPF concepts to WinUI3, which is arguably the more critical documentation to provide, and currently pitifully poorly documented.
Doubly so because it would help indicate a measure of feature equivalence; does WinUI 3 currently represent feature equivalence to WPF? Has XAML Behaviors been integrated as a member of the API?
Except it's still missing a lot of controls, further development and bug fixes are practically at a standstill, and despite what TFA says, there is no visual designer support (which is a dealbreaker for many multidisciplinary teams).
As someone currently involved in switching our app from MFC, I really want to like MFC, but Microsoft's absolutely addled management of the whole thing is making it really difficult.
In my opinion, WPF is the logical choice. Still.
Probably Windows.Forms unless there’s a REALLY good reason to do anything else.
Don't forget Avalonia. Looks like it's going to be the sensible WPF version.
Yeah, I can confirm that writing windows GUI apps is not at all painful for me. I still use Windows Forms in .NET 4.8 and my executables are < 1mb, Visual Studio's form designer is very easy to use, you can subclass all the .NET UI controls and customize them however you want. There's always been accessibility and even support for high DPI.
Do you need to ship any supporting files separately, along with the app?
And is .NET 4.8 or higher already on Windows PCs?
.NET 4.8 is default in Win10/11 now.
.NET 4.8 is the last .NET to be bundled with Windows. It's a legacy stack, but it exists on every Windows >= 10 so it is a legacy stack that makes deployables easy (just assume it is installed). (.NET 4.8 is the new VB6.)
With .NET 9 right around the corner, how far behind the legacy stack is only increases.
.NET > 5 will never be installed out of the box on Windows PCs. The trade offs to that concession however are: cross-platform support, better container support, easier side-by-side installs support ("portable" installs). .NET > 7 can do an admirable job AOT compiling single-file applications. For a GUI app you probably aren't going to easily get that single-file < 40MBs yet today, but it's going to be truly self-contained and generally don't need a lot of specific OSes or things installed at the OS level. Each recent version of .NET has been working to improve its single-file publishing and there may be advances to come.
A nice thing about .Net Framework 4.8 is that they finally finished it! No more update treadmill and dicking around dealing with what versions are installed or how to configure your application to use whatever different versions. Just target that and forget about it.
40MB seems like a weird requirement. If it’s under 1GB, I don’t think most people really care any more about executable size. Memory usage is still relevant, but 1GB is going to be less than 1% of disk usage for almost everyone.
1GB for each app accumulates really quickly. 40MB is really low, but I wouldn’t be happy with 1GB per app personally. Anything below 500-600MB is fine.
I want my disk space for large medias, not for a desktop app
Well that's the killer right there. I too think it's way too painful to write Windows UI, especially if you want to stay away from Electron (which you should in almost all cases), but refusing to pay money for good software is going to severely hamper your goals in 99% of cases.
Is this really still true though? VS Code and Slack are all quite polished and give me no issues as a user. Not sure what else I'd consider to build something similar.
Title is "Writing GUI apps for windows is painful", and then the author slaps on a bunch of bullshit constraints but pretends to be covering the general case. Sorry dude, if you want to do that then change the title to something appropriate like "Writing small, custom styled GUI apps for windows is painful". Otherwise this is bait and switch.
Implicit (for me anyway) in the title is that you are talking about vanilla GUI apps. Writing vanilla Windows GUI Apps is trivial and there are a bunch of tools that handle this extremely well. The article covers many of them but chooses to disqualify them for reasons.
Then we have ImGui as the tool of choice, but now this is qualified as only for "simple apps". Really? After all the fuss about constraints not being met? A bit of cognitive dissonance here I think.
More complex functionality things can get difficult but often even these are handled depending on the tools.
For vanilla dev the clear winner in terms of productivity has to be WinForms. Or if you can live with the clunky IDE - Lazarus. (You're allowed to replace with your own favorites.)
The real challenge is not writing GUI apps for windows, but rather is in writing cross platform apps.
"Writing small, custom styled GUI apps for windows is painful"
I'd add "for free because I'm too cheap to buy a license for a toolkit that does what I want".
I've gone through the same process of evaluating x-platform alternatives and I can now understand why Electron is so popular.
I mean, you do have the unreasonable bundle size, but other than that you can make really good looking applications using the same tools you can use to make web sites for both desktop and mobile.
I've been eyeing https://neutralino.js.org/ since if I'm going to make the app render right on browsers then relying on the same code via webviews likely isn't (much) more portability effort.
Agreed, this is a bit like writing ‘developing iPhone app is painful’ but not using anny officially supported tooling.
fact that you must ship the app Unpackaged is particularly strange.
Are you saying without an installer, or unpackaged as in without a package identity ala https://learn.microsoft.com/en-us/windows/apps/get-started/i... ?
Qt makes such amazing apps. I love KDE and the apps they spawned like Kate, KDEnlive, Krita.. It's no wonder their apps are so popular on Linux and windows alike. Unlike GTK apps even though it does have bindings for Windows.