
Golang Desktop App with Webview/Lorca, WASM and Bazel - grahar64
https://maori.geek.nz/golang-desktop-app-with-webview-lorca-wasm-and-bazel-3283813bf89
======
pjmlp
The workarounds one goes through to avoid native frameworks.

"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...](https://www.amazon.de/-/en/Andrew-Williams-
ebook/dp/B07GYLYSCT)

~~~
jmnicolas
If you want to have a multi platform (desktop) app, the only decent (imo)
framework is QT.

So now your app is either GPL or you fork something like 5 grands ...

~~~
pjmlp
Yeah, lets not pay the others for the fruits of their labour.

~~~
coldtea
People don't automatically deserve payment for the "fruits of their labour".
Only if you use it and can't find a better/cheaper alternative.

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...).

~~~
pjmlp
Except that look elsewhere seems to be understood as free beer around here.

$5000 is not the price for small developers by the way.

------
jchw
I just recently tried webview/webview in Go and was a little fed up with the
fact that it could not be a single-binary plug & play experience on Windows.
To that end, I am working on an experimental alternative that uses Webview2
directly without CGo: [https://github.com/jchv/go-
webview2](https://github.com/jchv/go-webview2)

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](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.)

~~~
zserge
I like the approach of go-winloader, I'd be happy to include an example of
using it with webview into the readme. I agree, including 2 DLLs on Windows is
ugly, however I believe that using CGo for webview would be a long-term win,
because new features of webview may emerge in webview.h and they will be
available in all language bindings immediately, including Go. I might be
wrong, but I think if there is a solution to include both DLLs (webview.dll
and WebView2Loader.dll) into a single executable in Go - that could simplify
life for everyone.

~~~
jchw
Honestly, if you embed both DLLs, the only thing preventing you from being
able to build with CGo off is the bindings implementation since it relies on
CGo features.

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.

------
WinstonSmith84
People complains about this setup but WASM is optional. I've been using Golang
with Lorca _without_ WASM. I actually don't see the value of WASM here..
Anyway, I used Svelte on the frontend, pretty straightforward but any other
lib would have been as easy to bind. And it just... works.

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

~~~
fileeditview
Sure you have the smaller distribution size. However you also have drawbacks.
As you mentioned Chrome must be installed. Then you can not guarantee the
Chrome version like this.. maybe the version the user has breaks your app.
Also you cannot use the "native" menu and other windowing features as you can
with electron. I am not really convinced by the "Lorca concept".

------
snarfy
My problem with these approaches, is what's the next step? Do you implement
GUI buttons on top of canvas and push pixels in WASM? Do you try and do
something like ImGui and use WebGL? None of these approaches are efficient. If
you are making a native app because it would be more efficient, I'm not sure
what the point of this approach is.

~~~
tyingq
It seems like the WASM folks have a plan to address it in the future.
[https://github.com/WebAssembly/proposals/issues/16](https://github.com/WebAssembly/proposals/issues/16)

------
Philip-J-Fry
Personally I'm a big fan of
[https://github.com/wailsapp/wails/](https://github.com/wailsapp/wails/)

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.

~~~
FeistyOtter
I am only familiar with Electron (due to its hype), what is native webview, is
it like a browser? If yes why is it better? Asking as someone who has never
developed any desktop apps.

~~~
flohofwoe
It's a minimal native application which creates a window with an HTML widget
in it, essentially a mini-browser wrapped in a native application. The
difference to Electron is that this browser isn't a bundled Chromium, but the
browser engine that's integrated with the operating system (Edge on Windows,
WebKit on macOS and Linux), so the application installer is much, much
smaller.

When I tinkered with
[https://github.com/webview/webview](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).

~~~
philsnow
> this browser isn't a bundled Chromium, but the browser engine that's
> integrated with the operating system

so I wouldn't have to worry about various electron app packages shipping with
versions of Chromium from three years ago?

~~~
flohofwoe
The downside is that as the application developer you no longer can control
the browser version your code is running on, so you may need different code
paths for WebKit vs Edge, or old vs new browser versions, but this is the same
problem normal webpages have to deal with.

But at least you can call out into native code and native operating system
APIs, unlike "real" web applications.

------
eivarv
In general, why would one take this approach of embedding a browser, compiling
to WASM, etc. over a native UI?

I'm genuinely curious why/when this is a better solution.

~~~
krageon
Building native UIs cross-platform is a huge PITA and frequently the
frameworks are also very annoying to use. I don't condone the use of browsers
for desktop software because it is a travesty, but it is very understandable
when you look at how we got here.

~~~
Gibbon1
You watch .Net core is going to curb stomp all that kind of crap.

~~~
sime2009
Can you explain how for those of us who don't follow .Net very closely?

~~~
krageon
It doesn't, because .net core doesn't ship with cross-platform GUI toolkits.
You have the usual options, which are all bad.

~~~
fassssst
[https://devblogs.microsoft.com/dotnet/introducing-net-
multi-...](https://devblogs.microsoft.com/dotnet/introducing-net-multi-
platform-app-ui/)

~~~
longstation
Linux is not supported.

~~~
Gibbon1
yet

~~~
krageon
From what I can tell of the repository, it's up to the "Community" to make a
Linux version of this.

~~~
Gibbon1
There are three problems. One that even with the resources MS has at it's
disposal it's taken them half a decade to make their framework cross platform.
Second it makes sense for them to target the big three that represents 95% of
the market. And Linux desktop isn't one of those. And third the Linux
community is hostile. Back in 2010 they could have embraced Mono which was
sorely needed but didn't out of just spite.

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.

~~~
krageon
The open-source community doesn't like Microsoft because Microsoft is hostile
to open-source. It's their MO to embrace things first and people with short
memories laud them for it every time. It's very disingenuous to quote their
hostility as one of the problems when really it's a logical historical
development. They're going to have to put in a lot more effort to make amends
for all the terrible things they've done over the years.

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.

------
ptrik
Carlo [1] was an exciting project to hear, sad that it's no longer maintained.
Glad to see Lorca [2] as a spiritual successor.

[1]
[https://github.com/GoogleChromeLabs/carlo/](https://github.com/GoogleChromeLabs/carlo/)

[2] [https://github.com/zserge/lorca](https://github.com/zserge/lorca)

------
steeve
Cool article!

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...](https://github.com/bazelbuild/rules_go/blob/master/go/extras.rst#go_embed_data)

~~~
grahar64
Oh, awesome. Didn’t know that was a thing will, look at that later. Cheers

------
_lobster
I generally recommend Sciter for desktop apps; The programming model is
extremely intuitive and straightforward, and in my experience, the performance
is excellent. Besides that, I'd look at something like webview

~~~
akrymski
I've considered using it, how has your experience been with regards to webkit
compatibility and performance? Did it render correctly out of the box?

~~~
_lobster
Yup, it renders correctly out of the box. Occasionally some small odd quirks
with more complex CSS styling though. I've done lots of development with Qt
and webview but saw significantly better performance in Sciter.

------
Maxence
Hello,

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](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.

~~~
grahar64
Hey, I love your go-app library! I wrote a blog post using it here
[https://maori.geek.nz/a-web-app-using-bazel-golang-wasm-
and-...](https://maori.geek.nz/a-web-app-using-bazel-golang-wasm-and-
proto-c020914f4341) and have used it on multiple small experimental projects.
I have plans to use your code, either as inspiration or direct dependence, for
many of my future projects! Cheers :)_

------
AnonsLadder
Well done, I too am building a desktop app in Go, I couldn't find a decent GUI
library and just resorted to packing a webserver & static files into my
program instead. For the time being anyway, still looking for Gui options.
Figured I could make a creative html/css UI instead of figuring out how to
create a GUI. I'd like to mess with Qt but the GUI builder is with their paid
licensing iirc i think, but it seems to be the only cross-platform solution
afaik

~~~
jcelerier
> I'd like to mess with Qt but the GUI builder is with their paid licensing
> iirc i think, but it seems to be the only cross-platform solution afaik
    
    
        {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 qtcreator

~~~
AnonsLadder
Thanks for mentioning, absolute game changer for me. I'm now using qtcreator
with Go bindings:
[https://github.com/therecipe/qt](https://github.com/therecipe/qt)

The multi-arch & especially Android deployment feature is exactly what I
needed, I can skip using Android-Studio/HTML as UI now

------
Jolter
Knowing next to nothing about Golang: Is it unlikely that someone would ever
develop an actual desktop toolkit for Golang? If so, how come?

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.

~~~
grey-area
Cross platform UI toolkits are a sisyphean task that everyone wants someone
else to work on.

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.

~~~
viraptor
> Platform vendors like Apple, Google, MS don't want to let developers target
> multiple ecosystems

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](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.

~~~
dvfjsdhgfv
You won' probably catch any exec from MS and Apple admitting the obvious, but
it's really against their best interest to encourage multi-platform apps as
this would give users a choice between operating systems. It's not something
that is discussed a lot these days because modern web apps are quite powerful,
yet it's clear a good quality multi-platform toolkit would be a boon to users
and developers alike.

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.

~~~
viraptor
I haven't tried to use it in anger, but [https://www.mono-
project.com/docs/gui/winforms/](https://www.mono-
project.com/docs/gui/winforms/)

"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.

~~~
dvfjsdhgfv
To clarify: you can't use Windows Forms directly with .NET Core on non-MS
platforms - you nee to port them to Mono.

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.)

~~~
Gibbon1
Be interesting to see what happens, MS is releasing.Net 5.0 That's supposed to
be cross platform and supersedes all the other stuff.

~~~
Multicomp
While the backends are unified, MS still do refuses to fix the UI framework.
They instead have yet another version of the post WPF scrambled egg UI
framework. AKA WinUI3.

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...

~~~
pjmlp
WinUI keeps being UWP, and by the way WPF is now officially in maintenance
mode.

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.

~~~
Aduket
> WPF is now officially in maintenance mode.

Can you share the official source of this statement?

------
LeoNatan25
If one is using Go/C++/whatever WASM, why not go the extra step and use a
binding framework for the OS's native UI toolkit, and just produce a native
app? I don't understand with the fascination of bringing an entire OS (the
browser) on top of an OS.

------
rajveermalviya
This is great but there many drawbacks. I tried Qt but needed something
native-er.

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/](https://gioui.org/)

[2]: [https://flutter.dev/](https://flutter.dev/)

~~~
beojan
Nativer than Qt? You could try WxWidgets, but really unless you use the native
toolkits directly, Qt is as native as it gets.

~~~
rajveermalviya
Oh yes.. I meant, completely in Golang.

And as far I know gioui tries to avoid Cgo where it can.

------
rwitoff
Does this lead to a significantly smaller memory footprint than otherwise
running .js in electron or a full browser?

I see you've become a big fan of bazel :)

~~~
akrymski
It's the difference between a new tab vs a new browser instance - every
electron app is a new browser instance with fixed overhead of 100mb or so. A
new browser tab is closer to 10mb overhead.

------
kgersen
see [https://www.vugu.org/](https://www.vugu.org/)

~~~
grahar64
This is cool, didn’t find this in my googling. Like with go-app
([https://github.com/maxence-charriere/go-app](https://github.com/maxence-
charriere/go-app)) though, it is a front and backend framework that seems
closely tied together. I would like to see a front-end GoLang framework that
can be reused easily. Still awesome, will take a look later

------
fmakunbound
Err, what you have there is a web app.

------
zachrip
_But I don’t want to write JavaScript(!) and deal with all the complexities
that comes with it like npm, webpack, typescript… Fortunately, I can just
compile GoLang to WebAssembly (WASM)_

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.

~~~
rkwz
I wrote a simple webapp using Rust (Wasm, Yew) and the payload is 130KB
gzipped - [https://rustmart-yew.netlify.app/](https://rustmart-
yew.netlify.app/)

Repo: [https://github.com/sheshbabu/rustmart-yew-
example](https://github.com/sheshbabu/rustmart-yew-example)

