Golang Desktop App with Webview/Lorca, WASM and Bazel
maori.geek.nz
maori.geek.nz
"Hands-On GUI Application Development in Go: Build responsive, cross-platform, graphical applications with the Go programming language"
https://www.amazon.de/-/en/Andrew-Williams-ebook/dp/B07GYLYS...
The "old" frameworks such as the GTK bindings are either unmaintaned or not complete or both. The new frameworks like Gio and Fyne are promising but not there yet. Maybe in 1-2 years if they are being worked on consistently.
I really wish to do my upcoming project natively in Go (also Rust would be fine) but I don't see how.
Regarding web technology as desktop solution: all of those solutions including Go are just a mess IMO. They force go into the stack even when it doesn't make sense. Write the frontend in Go, compile it to WASM, wrap it in some browser.. it's just more complexity for no real gain.
There are some promising ideas, such as webview and wails but again not production-ready.
My conclusion: if you are willing to use web technologies, just use electron at the moment.
With Go the only "possible" way is to write a server and open a tab in your browser. But if people would accept this as desktop solution is another question.
In last years a lot projects have appeared, which were trying to compete in GUI toolkit market share. All of them had its scope limited, however they brought quite fresh look on declarative programming interface [0][1], superb 2D rendering pipeline [2][3], ease of embedding [4] and adaption to low-power devices [5] but none of them is "complete".
Personally, I am amazed of the implementation of rxi/lite [6], which is just an app (C with Lua) based on SDL2 library. It uses 2x less RAM than sublime on 1GB file, has lower latency, covers clipboard, keyboard, mouse, drag and drop, some context menus but does it feel native? No. Among many issues, it is easy to report an error with screen-reading software but it is quite common problem in all aforementioned.
Perhaps in future, something like LSP specification will see a daylight, which in outcome will helps us to provide universal, modular, limited to certain scope libraries that can be easily plugged in case of need. Maybe then we will came closer to "native" GUIs. In my experience, there are numerous developers who were trying hard to deliver "complete" GUI toolkit but have failed.
[0]: https://github.com/cycfi/elements
[1]: https://flutter.dev/
[2]: https://github.com/linebender/druid
[3]: https://github.com/servo/pathfinder
[4]: https://github.com/ocornut/imgui
rxi/lite have tens of functions in C to provide operation of file-system, implement fuzzy-finder or simple rendering calls for rectangles. Rest of code is written in Lua that shares a lot of signature-compatible functions with Sublime Text API. There is only Lua, STB (stb_truetype) and SDL2. Also compilation script is basic shell script [0].
It is also worth noting there is interesting contribution to provide sub-pixel rendering [1] (now, a fork [2]) which includes usage of libagg [3].
[0]: https://github.com/rxi/lite/blob/master/build.sh
[1]: https://github.com/rxi/lite/issues/145#issuecomment-64155409...
So we have QT and GTK ...
gotk3 is maintained and most of the widgets are in place (technically it's not "complete", sure, but still).
My biggest gripe with it is that the whole documentation is just absolutely useless string of "this function is a wrapper for this function in C" over and over again instead of it being, well, the documentation for the function that is being wrapped.
But good to know. And yes I forgot to mention the documentation.. you are absolutely right.. so far I have had that experience with all things GTK.
That split model isn't limited to browser tabs. You can write a nice GUI (native, or tooling of your choice) that communicates with your go back-end via API bindings.
This model is well proven (dockerd/docker cli; various crypto wallets and their front-end UIs, etc), though attention needs to be given to security concerns. Running a local service means malicious software that knows about the service could access it without the user's knowledge if you're not careful, exposing private or sensitive data that the service has access to.
Can you clarify these security concerns? If the server is only listening on localhost I don't see a difference to "the classic desktop application". If the malicious software has access to your system the data is always endangered right? Or were you talking about services that are exposed to the outside?
That's what I meant as well. You have a go daemon/service running that does the heavy lifting; and your front end (whatever it may be) knows how to talk to it. The UI elements remain separated from the work of the daemon.
The browser-based/localhost approach works well for this too, but you can also take the same approach for rich/native client apps without having to make the daemon platform-specific.
> If the malicious software has access to your system the data is always endangered right?
This is what I was referring to - nothing new, but IMO worth mentioning in the context of setting up a new service to run on someone's system.
So now your app is either GPL or you fork something like 5 grands ...
Think Visual Basic but cross-platform, with a much better language and component architecture.
You can develop non-trivial apps in hours rather than days.
The IDE is here: www.lazarus-ide.org
Why Lazarus?
* Has a proper Rapid Application Development (RAD) IDE with visual layout, event handlers, component tool bars etc and also built in documentation
* Extremely fast to develop on: The IDE starts in a couple of seconds. Compilation to native binaries in seconds.
* Cross Platform - Windows, Linux, Mac OS and perhaps even Android
* Binaries are really fast
* Excellent set of visual components
* Excellent set of database components including grids, CRUD toolbars etc
* You can write your own components very easily.
* Very small executable
* Most Delphi documentation is directly usable
* Many existing products use Lazarus https://wiki.freepascal.org/Projects_using_Lazarus
* Demos and projects here: https://www.getlazarus.org/
I've actually done this, it works well, and the Lazarus GUI libraries manage to get a natural look and feel on all platforms.
Are you the person who wrote this? if so would like to contribute in some way.
I tried it a few years ago and ran away for this exact reason : I have VB PTSD from some complex Excel apps that I inherited at work ;)
But yeah if I was objective I could see a lot of value in Lazarus.
What the parent suggested was not using QT and not paying the company that makes it, but that its price makes it unusable for their purposes.
(Now, that might have been based on a misunderstanding of the licensing involved, but ignoring that, the point still stands. If one had to pay $5000 for a GUI library, and one didn't have $5000, then one could look elsewhere...).
$5000 is not the price for small developers by the way.
It is licensed under the LGPL though (however much its current owners may want to change this, they can't because of the KDE Free Qt agreement), which means you don't have to pay. All you have to do is dynamically link to the library instead of statically linking.
The major contributors for Qt have always been the same regardless of the legal name of Qt owner.
It is quite easy decision process, don't want to pay for Qt's development, use LGPL and GPL variants earn as much money as one is willing to give upstream.
Decide to go commercial, then pay accordingly upstream.
> Decide to go commercial, then pay accordingly upstream.
Hmm. The commercial license actually prohibits starting development under one of the open source licenses then switching to commercial. If you start under an open source license, you'll need to abide by the LGPL if you decide to go closed source (and of course what you've already released remains open source).
https://www.gnu.org/licenses/gpl-faq.en.html#LGPLStaticVsDyn...
Note that does not necessarily require “your code” to be/come open source.
Wasn't there talks about ending the lgpl version ? I thought I read somewhere that KDE devs were quite worried.
As far as I can tell from that the LGPLv3 seems to be required under the current terms of the agreement.
It still requires WebView2Loader.dll, but I am working on another library so I can just embed it directly into the application, and that work is happening over here: https://github.com/jchv/go-winloader
Sorry for the blatant self promotion, but I thought fellow stubborn people might have a desire to drop to as few dependencies as possible. I prefer building without CGo. The only downside is there’s not really a great way to fall back to EdgeHTML so users will need a Webview2 install, and right now Windows isn’t shipping it, but I think going forward it will be reasonable to just link users to the webview2 runtime page to go install it.
(Also, it should go without saying, but this approach only improves things on Windows. You will still need other bindings for other platforms.)
However, it might be possible to have one’s cake and eat it too here, if there is one implementation using Windows-specific Go features that embeds the DLLs and one implementation that uses the existing CGo approach on other platforms. Essentially, the binding to webview.h would be abstracted away from the Webview Go interface implementation.
I will continue to work on go-winloader in my spare time, and hopefully will have an interesting webview pull request in the near-ish future.
What I'd like is to help make upstream webview/webview more self-contained somehow, but for now a possible approach is to just use go-webview2 for Windows and then webview/webview for everything else. My approaches to lower dependencies may not be accepted upstream webview/webview: direct bindings to Webview2 mean no EdgeHTML fallback + code duplication from the C bindings, and go-winloader is (WIP, it doesn't even work yet) a fairly complex piece of code that would be an additional dependency.
(Just so it's clear, I do actually want to make a concerted effort to try to support an EdgeHTML fallback, but it will effectively be based on directly binding to MSVC ABI from Go, and therefore will be a lot uglier than the current Webview2 code that just deals with COM interfaces directly.)
The main advantage over Electron is the size of the bin (~20MB for a medium app vs. >100MB if it was Electron). If you know the people who are going to use your app have Chrome installed, it's definitely better than Electron and you get the best of both worlds - quick crafted & beautiful UI and performant backend
I like it when people explore different avenues like this. Often nothing really comes of them, but you never know.
It uses native webview so no electron. Let's you effortlessly bind JS functions to those in Go.
V2 is in the works and will effectively bring the best features of electron window management (menus, frameless windows, drag regions etc) over to native webview.
Currently uses IE11 on Win 10 but V2 will only support Edge so you get WebKit across the board.
The new Edge browser uses Chromium, not WebKit, so still two different browser engines to deal with (essentially Chrome vs Safari).
99.9% of the time your pages render the same on Safari as they do in Chrome because it's effectively WebKit.
The only real difference between WebKit based browsers is experimental features. They all follow the core standards now which IE11 didn't.
When I tinkered with https://github.com/webview/webview on macOS a minimal Hello World application was around 26 kBytes (kilo, not mega), which is about 7000x smaller than a default macOS Electron instance (173 MBytes).
so I wouldn't have to worry about various electron app packages shipping with versions of Chromium from three years ago?
But at least you can call out into native code and native operating system APIs, unlike "real" web applications.
So your binaries can be really small too. Seems like faster start up times also.
I'm genuinely curious why/when this is a better solution.
Unlike Electron, Webview does not embed a browser, but uses the platform-native browser engine. That's Cocoa/WebKit on Mac OS and Edge on Windows. Since Linux doesn't have a one, gtk-webkit is used there.
This allows for very small binaries, but necessitates dealing with the platform incompatibilities.
Given this experience, I just don't get how cross-platform UI-frameworks are somehow a bigger PITA than pulling in and involving a whole other set of technologies.
Brings up a third point when talking about development. Microsoft is providing a posix compatible dev environment under Win10. The threat that poses is completely unappreciated.
But all of that is really beside the point. Saying the "community" needs to fix it means they won't put time or effort into doing it themselves, which by extension means the integration will most likely never be as good as what they have prioritised. This will relegate their "cross-platform" solution to the realm of all the other frameworks: Bad.
I mean ideally you'd create a native application for all operating systems and use their native frameworks, but you need to hire at least two developers (for redundancy / knowledge sharing) per platform and it'll be a constant struggle to keep features aligned. It can be done, but you need a clear vision, alignment, some independence for the native app developers, etc.
But it's pretty much unfeasible for solo developers.
Given that most of these have bindings to many languages, I don't understand why one would involve a browser-runtime and whole other set of technologies.
Two Qt apps that I use are Calibre and Ripcord, the two ugliest apps on my computer. Not that I'm complaining, but never lines up with HN's why-would-you-use-a-browser Qt praise.
The fact that it's possible to not build an "app that looks native or actually looks good" doesn't imply that it's impossible to build one that does, though.
And I actually tend to prefer wxWidgets, as this wraps the platform's native widgets proper, whereas Qt reimplements many (all?) widgets, but attempts to offer a native look-and-feel.
Regardless: Actual GUI-frameworks have huge advantages to using a browser, like:
- Better performance
- Visual and UX consistency (HCI, people!) on a shared platform
- Smaller sized apps
- Drastically reduced resource and energy usage
[0]: https://en.wikipedia.org/wiki/Category:Software_that_uses_Qt
And again we managed as solo developers, or with very tiny teams to do that in the context of 8 and 16 bit home micros, which meant writing lots of Assembly and hardware specific code in the process.
So I guess strangely younger generations cannot manage to go to school bare foots uphill in snow both ways.
Small note: you can use rules_go's builtin go_embed_data [1] rule instead of rolling out your own using genrule.
1. https://github.com/bazelbuild/rules_go/blob/master/go/extras...
{apt, brew cask, choco} install qtcreator
it's entirely free & open-source. there is Qt Designer Studio which adds a couple of convenience functionalities if you are making e.g. embedded appliance dashboards but for 100% of desktop UIs you have everything needed in the LGPL qtcreatorThe multi-arch & especially Android deployment feature is exactly what I needed, I can skip using Android-Studio/HTML as UI now
Are you meaning the UI designer built into Qt Creator?
I'm super happy to see that some folks are trying to make apps with Golang.
I'm myself the author of a Go package to build GUI with WASM and Go => https://github.com/maxence-charriere/go-app
WASM give us an incredible amount of new possibilities and hopefully, we will get to a point where Go will be used in production also for GUI/apps purposes :)
Congrats for this and good luck for the future.
From a naïve point of view, it would seem like overkill to run a whole web browser when a few kilobytes of memory is all it really takes to draw a widget on screen.
Platform vendors like Apple, Google, MS don't want to let developers target multiple ecosystems - they want a monopoly on devs and users, hence the endless churn of languages, frameworks and SDKs, making it difficult to keep up.
It's much easier and more reliable to use HTML, even if the experience isn't as slick for users.
Is this actually true? As in, I see how we may arrive at the same outcome anyway, but at this point, do those companies actually care about aggressive lock-in?
- Apple seems to be more ignoring the possibility of SwiftUI on other platforms rather than actively preventing it since https://github.com/Cosmo/OpenSwiftUI (dead) exists. Sure, they will never help to make it happen, but "don't want"?
- Google is pretty much cross-platform/-ecosystem with Flutter which explicitly supports iOS.
- MS seems to have given up with Win Forms opensourced and working on .NET Core / Mono.
MS does not care what OS you use anymore. They want users of all operating systems to order their Office 365 license and run all their cloud compute loads in Azure.
As for MS open sourcing .NET Core it's all good and nice, but WinForms and WPF are still Windows-only, and according to MS they will remain this way. And Apple has no intentions of doing the same with SwiftUI.
"Support for Winforms 1.1 and 2.0 has been completed, and is now in a maintenance/bug fixing state."
"System.Windows.Forms implements its own driver interface to communicate with the host OS windowing system. Currently, we have drivers for X11, Win32, and macOS. These drivers translate the native window messages into WndProc compatible messages, to provide as much compatibility with native .Net as possible."
WPF is windows-only though.
I tried to use Mono several times, starting from Ximian and Xamarin times, and I always encountered strange problems that were not present in the original applications. I hope they improved somewhat recently because the code produced back then was often unusable (e.g. huge leaks after a couple of hours of use.)
the native grumpy old people like me will continue to use Windows forms or WPF or MFC,ATL,Win32.
The masochists will try to use the open-source silverlight replacement. Moonlight?
The futurists will use Avalonia. Maybe SAFE stack MVU via Fable?
The Microsoft contractors will use WinUI3.
Vast majority of web developers today will use electron, as unfortunate as that is...
Your Silverlight replacement would be OpenSilver.
The cross platform toolkits would be MAUI (nee Xamarin) and Blazor.
Electron is the new Active Desktop/XUL, its fashion phase will eventually fade away.
Can you share the official source of this statement?
Mono is not meaningfully cross platform and is not the official Windows SDK.
The iOS SDK is not cross platform and changes frequently leaving behind it a trail of dead x-platform projects like the one you cite.
I suppose there are multiple reasons for this lack and it may not be a deliberate strategy in all cases but there is no incentive to promote cross platform work and there are multiple incentives for corps not to. These platforms are made to corral users and devs, not to share them.
If you need to draw a widget on the screen, there's Dear ImGui [1] that you can use from Go [2]
If you're looking for a desktop toolkit, there's a reason why things like Qt are multidecade endeavours.
After much digging got to know about gioui[1] but it also has some issues. Also Flutter[2] seems to be better fit but binding to golang is a little tough.
[1]: https://gioui.org/
[2]: https://flutter.dev/
And as far I know gioui tries to avoid Cgo where it can.
I see you've become a big fan of bazel :)
Okay...
Large WASM binaries (especially from GoLang): these take a long time to send over the network increasing loading times. In a desktop app the binary isn’t transferred over the network, so less overhead.
I forgot that you don't have to download desktop apps, they just appear!
Browser incompatibility: Some WebAssembly methods are unavailable in browsers and older browsers are not supported at all. In a desktop app the “browser” is controlled (Chrome for Lorca and Safari for webview), so no compatibility issues.
Electron???
This just seems like you built a less easy to use bundling/development platform than js/webpack/etc and claimed it was better when I'd argue it's way less mainstream and thus less accessible. Not to mention you could've just used native ui like others are talking about. Seems like the worst of both worlds to me.
This seems disingenuous, given how clear the difference of bandwidth utilization between a web app and a desktop app is during setup.