return to table of content

Gio UI – Cross-platform GUI for Go

bsaul
58 replies
1d8h

A bit off-topic, but what's the best method to build cross-platform mobile & web apps nowadays ? I'm talking either business logic + UI , or just business logic ?

like gomobile, rust, typescript, etc ?

At some point i thought about using typescript for all business logic, as it seemed the most portable tech, but i realized there's no good way to have decent performance running javascript on iOS.

brabel
11 replies
1d7h

The best option is probably Flutter right now: https://flutter.dev/

If you don't mind writing the UI native, sharing only business logic code, Kotlin is an option: https://kotlinlang.org/docs/multiplatform.html#kotlin-multip...

Kotlin also can do the UI if you use Compose: https://www.jetbrains.com/lp/compose-multiplatform/ ... however, iOS support is still in alpha, and Web is "experimental". If you're not willing to cope with that (expect to have to change your code as they develop the framework) then Flutter is the way as it's pretty stable already on all platforms.

If you already know Typescript and React, you may also consider React Native (but I can't attest to its performance on iOS or anywhere else): https://reactnative.dev/

salomonk_mur
2 replies
1d4h

Why would the ability to modify HTML matter at all? Most users don't even know what HTML is, much less how to open the dev console.

wiseowise
0 replies
1d

Yeah, why does it even matter if you can control a page? Let’s just make it a fucking canvas, power users and those who care about web experience can go to hell.

mrighele
0 replies
19h47m

Regular users know how to install an extension that interacts with the DOM, though

Alifatisk
2 replies
1d3h

You can export the flutter build as HTML, but the point with flutter is not to be a ”website”, it’s supposed to be seen as a ”web-app”.

If you are going to create simple static homepage or interactive website, I don’t think Flutter is the right tool. Full fledged cross-platform applications is what Flutter is meant for.

38
1 replies
18h16m

I agree, who cares if a website supports accessibility, no one in the world is vision impaired and uses screen readers right? right?

Alifatisk
0 replies
6h52m

That's not even my point.

Websites should still support accessability, I would even go as far to say it's a must. I just don't want people to mix up web-applications with websites. I've seen some people create a simple "websites" with Flutter which is totally pointless because it could just been created with html + css.

There is also a section in the Flutter docs that talks about accessability and how you can create accessable apps but I don't know how well it translates to Flutter web.

https://docs.flutter.dev/ui/accessibility-and-internationali...

jagger27
0 replies
1d1h

And it has laggy scrolling. What’s the benefit?

lessisless
0 replies
1d

A long time ago, nativescript[1] seemed to be a strong alternative to reactnative. Is that still the case?

[1] https://nativescript.org/

lakomen
0 replies
1d5h

If you use oidc, you can't use Flutter with web or desktop as build targets. It requires a feature that isn't supported by Flutter on those platforms.

iamkonstantin
0 replies
1d1h

I would also add Tauri to the list as they now support mobile as well https://v2.tauri.app/blog/tauri-2-0-0-beta/

I think all cross platform frameworks come with some kind of drawbacks and in most cases, learning about the underlying native platforms is unavoidable (like widgets, visionOS support etc).

So I wouldn’t worry too much or get into a FOMO decision block - I’d pick the one that feels most fun and fits your use case.

scosman
7 replies
1d4h

Native UI for anything that requires polish. I’ve been through too many iterations of frameworks that promise everything and don’t deliver. You’re up and running faster, then soon after you’re patching the core libraries after an OS update to try to get the FPS closer to native, or match a system animation more closely. The time saving only exist if you never polish your UI.

Core logic can be shared. I use gomobile - mostly love it but 3mb overhead for runtime (so not for web). Kotlin multi platform looked good, but I found it missing pretty basic libraries (which exist for Kotlin Android, so no one is building multi platform equivalents). Rust with Mozilla’s language binding layer looks good but I haven’t tried it.

mdhb
6 replies
1d

I don’t think that premise of “native UI for anything that needs polish” is true these days.

Canonical the company behind Ubuntu have said for some time now that all future app UIs of theirs would be done in Flutter starting with the very first thing people see the installation process.

Google just rewrote Google Earth’s UI in Flutter.

BMW are doing all of their in-car entertainment systems in Flutter.

scosman
3 replies
10h17m

Two of the examples mention are platform providers. If they standardize on flutter as their native UI, that’s fine and they are following my suggestion. If they port a BMW app from my dashboard to iOS / Android, I’m 99% sure you’ll see the issues I mentioned.

Google earth is fine, but doesn’t feel native. I think that’s fine for some apps (games mostly).

mdhb
2 replies
9h44m

Could you maybe provide a single clear example of how Google earth doesn’t feel native?

scosman
1 replies
4h56m

Welcome screen was a popover on iPhone (only available on iPads, should be a sheet on iPhone), with rounded non standard button and non standard horizontal lines.

“Signed in as” toast wasn’t designed for iOS rounded bottom and “swipe up” bar leaving ugly stripe.

Sheet easing is off, and FPS stutter.

No swipe from left to go back support.

Non standard animations all over. Visible FPS issues (on newest HW)

I could go on and on. Feels like an android app running in an emulator.

mdhb
0 replies
2h21m

I think several of your examples appear to be confusing Google’s material design system with the frameworks capabilities.

deergomoo
1 replies
20h28m

Are any of those better than the alternative, or just cheaper?

I suppose if the alternative is “this only exists on one platform” or “this doesn’t exist at all” then maybe, but I find it a bit sad how keen we are as a profession to accept compromise and mediocrity to save developer time and expense.

I get it, but I don’t like it.

mdhb
0 replies
11h57m

2/3 of those examples had no requirements for cross platform and still chose it anyways. Additionally all 3 of those examples decided to take what they already had with native and decided to rewrite it because of the benefits.

I’m saying the “gap” between Flutter and native in this case is much much much smaller than you seem to think it is. Quite a bit has changed there in the past year or two.

That isn’t my opinion but that was the result of many major and very competent teams coming to that conclusion and putting their money where their mouth is in order to substantiate the claim.

ricardobeat
5 replies
1d7h

My team achieved better than native performance using RN when rewriting a very large iOS app. And that was in 2018, before Hermes and a lot of other optimizations.

It takes some careful usage of requestIdleCallback and avoiding doing work in the UI thread but it is not rocket science. You do have to avoid a lot of the going advice and bloated libraries / frameworks though.

robterrell
2 replies
1d2h

better than native performance using RN

You had an app written natively in Objective-C or Swift, switched to single-threaded javascript React Native, and then your app ran faster?

wiseowise
0 replies
1d

Unoptimized native application, probably written in a yolo let’s ship it faster way, is slower than rewrite that learned from mistakes of previous application. What makes you surprised?

ricardobeat
0 replies
19h4m

Though JS is single-threaded, it only builds the render tree and is more than fast enough if you’re careful. RN has a separate UI thread for actual rendering, I/O is offloaded and extensions can use extra threads.

The largest bottleneck historically was the bridge between obj-c and js (now superseded by JSI), and not the speed of the engine itself.

mradonic
1 replies
1d7h

| better than native performance

Maybe better than the native you had before the rewrite lol

ricardobeat
0 replies
19h24m

“The app we had before” had 50M+ users, developed by a large iOS team, including a lot of experienced developers working on performance, and generating billions. I think it was a valid baseline.

lakomen
4 replies
1d5h

Thanks, which of the two would people recommend for a C# beginner? And is oidc well supported on all target platforms?

neonsunset
2 replies
1d4h

Both frameworks have various packages that add OIDC support to them so that shouldn't be an issue.

As for beginner - there's quite a bit of learning curve in terms of writing GUI applications themselves. Avalonia is kind of like WPF* but good(tm) and cross-platform. Uno platform is more like Xamarin and MAUI except in a better shape as of today. From technical perspective, Avalonia focuses on consistent rendering on all platforms with Skia while Uno tries to use native controls instead. I generally would not advise using Avalonia for mobile over Uno. In mobile case you might actually want to also give MAUI a try as, despite harsh criticism it has been receiving, it has improved significantly.

* either platform supports various declarative UI libraries (that are either part of their ecosystem or community-maintained), so you are not married to XAML thankfully.

cseleborg
1 replies
22h40m

That's a great answer, very helpful. I just picked up Avalonia for a test drive. Why do you think Uno is better than Avalonia for mobile?

neonsunset
0 replies
20h36m

Performance on mobile devices and UI libraries. Avalonia ecosystem is predominantly focused on desktop, which is not the case for Uno. But I liked the fact that setting up and AOT compiling Avalonia templates was a breeze so use it for side projects. For something more serious that has to target mobile, I would investigate how much MAUI has progressed in terms of quality and if problematic, would just go with Uno.

cjbgkagh
0 replies
1d3h

If you are to use Avalonia, which I highly recommend, it may be best to start with WPF. The Visual Studio Community Edition has really good IDE support for WPF and there is a huge amount of information on how to do things in WPF which thankfully hasn't changed in a very long time. Plenty of old books and blogs that go into all manner of detail. Once you have what you wanted working as you want it is straightforward to port the WPF to Avalonia for cross platform support.

Yes this would necessitate using Windows, an OS which I abhor, but as of now . In time I hope that will change with improvements in both JetBrains Ryder and Avalonia.

andsoitis
4 replies
1d4h

what's the best method to build cross-platform mobile & web apps nowadays ?

Uno (https://platform.uno):

* open-source

* targets Android, iOS, Windows, Mac, and Linux (https://platform.uno/platforms/)

* C#

* automatically implements views and controls using each platform's native UI frameworks

* good IDE support: Visual Studio, VS Code, Rider (though you are not limited to those)

* Figma plugin for design collaboration

mort96
2 replies
1d4h

I mean I guess that's fine if you're into .NET but how about those who prefer to avoid that

balencpp
1 replies
10h39m

Why would you avoid .NET?

mort96
0 replies
7h14m

Not generally a huge fan of locking myself into Microsoft platforms

noveltyaccount
0 replies
1d2h

Also in the .NET world, Maui Blazor Hybrid is interesting. Uses HTML and the platform-native web renderer for the front end, and compiles to native code (not WASM)--i.e. clicking a button on your HTML invokes native code. Depending on your front end library, the app will look and feel more or less like a native app or web app.

An older article but puts it in context with Electron and how they differ https://www.codemag.com/Article/2111092/Blazor-Hybrid-Web-Ap...

kitd
3 replies
1d7h

In Go land, there's Wails

https://wails.io/

lakomen
2 replies
1d5h

What are all the target platforms? The website doesn't have a list, or I'm unable to find one.

EDIT: never mind, I found it https://wails.io/docs/reference/cli#platforms

It doesn't seem to support Android, IOS or web.

peddling-brink
0 replies
1d

Wouldn’t those be the server platforms?

leeman2016
0 replies
12h48m

Aren’t those platforms for the dev machine on which you would write the code and build you app?

Edit: looks like it’s for the server machine

devjab
2 replies
1d8h

We use Tauri, but I think that it’s important to know that we solely use it for internal tools. I have no idea if it’s a good tool for consumer facing products. It works well enough for what we use it for, which is mostly for our solar park technicians where using cross platform Typescript on terrible internet became too much work for our small team.

junon
0 replies
1d7h

We use Tauri at GitButler and love it.

DreaminDani
0 replies
1d5h

Agreed. Tauri for desktop, capacitor for mobile. Bring your own front-end library either way.

raminf
1 replies
20h11m

For mobile, this looks promising: https://skip.tools

Transpiles SwiftUI over to Kotlin/JetPack Compose. Native all the way down. Haven't used it in production, but the demos work and are native after going through XCode and Android Studio.

malermeister
0 replies
9h23m

first-class development environment (Xcode)

this made me lol. As somebody who does mobile dev professionally, the worst thing about iOS dev is how terrible XCode is compared to Android Studio.

There's no way I would want this.

petesergeant
0 replies
1d7h

I’m getting on pretty well with Ionic + TypeScript, using React and Redux. Performance hasn’t really been an issue, although I’m also not doing anything that performance heavy. I’d recommend it. I like that it ends up being comprehensible HTML + CSS, as well as simple React that I’m already comfortable with and can debug.

paulddraper
0 replies
1d3h

Expo targets iOS, Android, web.

mdhb
0 replies
1d7h

Flutter is so far in front of anything else out there I think at the moment.

marcusbuffett
0 replies
18h19m

I tried React Native, but ended up re-writing and going with SolidJS + Capacitor, and I love the setup. I've barely thought about performance since switching, people think the iOS/Android apps feel native, there's almost never any differences in behavior between the platforms, it's a fantastic setup for a solo dev.

ludwik
0 replies
1d6h

I tried quite a lot of multiplatform frameworks in the context of mobile, and for me Flutter is in a completely different league than the rest of them. I really love it.

felipefar
0 replies
17h21m

I would mention as an alternative QML, although I wouldn't claim it is the "best method". It's marketed as being mobile-capable, but I've heard problems about scrolling inertia and vsync delays.

I'm curious to know what others think about it.

divan
0 replies
1d5h

For the last 4 years the answer is Flutter.

bossyTeacher
0 replies
1d4h

You already answered your own question imo. The web is the best thing we have so far and nothing comes closer to the full package. It literally is write once and write everywhere.

All the other alternatives are young frameworks that have not been battle tested and have weird quirks once you want anything relatively complicated.

SoKamil
0 replies
1d7h

I would say React Native with all the Expo stuff. While Flutter is okayish, web is bad in terms of feel and accessibility since it renders to a canvas. Also, iOS still has issues with lag even after introducing Impeller rendering engine.

Look at Bluesky's client. The app performs decent on all supporting platforms and has single codebase.

https://github.com/bluesky-social/social-app

Robinxd
0 replies
1d5h

Has been posted here before also, so adding it for people not aware of it already - https://areweguiyet.com

Pepe1vo
0 replies
1d8h

What's your definition of decent performance?

My company has built quite a few complex capacitor + Angular + Ionic apps and the performance on iOS is fine. Some even got featured by Apple, so that should be some indication that quality and performance was alright.

Alifatisk
0 replies
1d3h

Flutter

shrubble
36 replies
1d6h

The amazing thing is that 30 years ago there were cross platform toolkits like Neuron Data and the toolkit under OpenOffice(called StarOffice originally), and yet today the options are still fragmented and imperfect.

We have far better compilers and even languages for cross-platform work, so it should be easier by now.

elteto
9 replies
1d4h

Why would it be easier now? What does a better compiler get you in terms of building a cross-platform UI toolkit?

We now have GPUs, mobile OSs with their own separate UI abstractions, the web, WebAssembly, etc. And people want write-once deploy anywhere.

You didn’t have any of that 30 years ago.

hulitu
4 replies
1d3h

You didn’t have any of that 30 years ago.

Java ?

avhon1
2 replies
1d2h

Java was introduced slightly before the cutoff -- 23 May 1995, so almost exactly 29 years ago. The earliest ancestor of its Swing desktop GUI library, called Internet Foundation Classes, was released 16 December 1996.

anthk
1 replies
1d2h

Inferno looked nice.

luismedel
0 replies
1d

The toolkit was Tk, IIRC.

elteto
0 replies
20h41m

I don't understand how Java is relevant here? Perhaps I'm missing your point.

My point was that making GUIs today should not be any easier than 30 years ago because we have a lot more complexity across different OSs, phones, and the web.

Update: I think I understand your comment. I think you latched on the very last past of my comment about "write-once deploy anywhere". I meant that as in people want to create their GUIs with one language and one toolkit and have them deployable across different stacks without having a custom version for each and every final target platform.

Yes, technically Java did deliver on that as a programming language and runtime. And I guess swing also deliver on that as a cross-platform UI toolkit. However, we don't see a lot of Java UI applications around, with the exception of a few big ones, so it's fair to say that in the end it didn't work out. Of course, Java as general purpose language and runtime is alive and doing well today.

shrubble
1 replies
1d4h

The compilers of 30 years ago had incompatible behaviors between OSes, for instance C or C++ had a great deal of variation. And 30 years ago you had pre-OSX MacOS as well.

Now you can just choose 1 compiler such as GCC and it works the same on all platforms; even cross-compiling to a different CPU architecture works well and is far easier to setup (before it was a black art).

Longhanks
0 replies
1d1h

In what way does GCC play any role in cross platform GUIs whatsoever? It’s a very small niche on Windows, macOS, iOS and Android. Visual C++, respectively LLVM/clang are much more dominant on those, and even then they are barely the right tools for GUI (maybe except Windows, but even then competing with .NET).

supportengineer
0 replies
1d1h

Pre-Java there was a need to have UI applications that ran on Windows NT as well as Solaris and HP-UX. I worked with a commercial software package called Visix Galaxy. We developed in C++. It included libraries for each platform. It also had an interface builder very similar to those today (like the one in XCode). These were polished tools that made it easy to build beautiful GUIs.

igouy
0 replies
1d

You didn’t have any of that 30 years ago.

"Ubiquitous Applications: Embedded Systems to Mainframe"

"To support a variety of platforms, Smalltalk uses a virtual machine approach to portability that allows applications to be easily migrated between platforms with little or no change to the code."

https://dl.acm.org/doi/pdf/10.1145/226239.226264

~

"… Smalltalk developers can work and deploy on Linux, Windows, AIX®, Sun Solaris, HP-UX, and OS/2®. You can also create applications to be deployed on the mainframe with VisualAge Smalltalk Server for OS/390 and z/OS."

https://www.ibm.com/docs/en/announcements/archive/ENUS202-10...

zackbrown
5 replies
1d3h

Building a cross-platform GUI toolkit takes an incredible amount of work & time, especially at the systems level.[0]

A robust cross-platform ecosystem for the underlying programming language is a necessary but insufficient piece of the puzzle.

Given the proliferation of HTML and WebView/web-tech wrappers (Electron, Tauri, React Native etc.) there are now enough "good enough" solutions that most organizations that would underwrite the in-house R&D of a new Neuron Data or Delphi or Flash simply don't feel the need.

When it does happen — say Google Flutter — it's almost statistically impossible to keep the hydra of VPs and biz folks aligned over the decades of ongoing investment it takes to mature & form community around this kind of technology — see the recent Flutter team layoffs at Google.

[0] speaking from my experience building a cross-platform GUI solution in Rust for several years now; see pax.dev

rohansingh
2 replies
1d2h

Isn't the whole "Flutter team layoffs" narrative somewhat debunked at this point? My understanding is that some positions were cut and some were moved, but no more than any other engineering area at Google.

zackbrown
0 replies
1d2h

Budget was cut because priorities were stacked and Flutter wasn't high enough. That's exactly the existential risk when beholden to "the hydra."

kernal
0 replies
15h4m

Yes. Layoffs were across all departments.

TheCleric
0 replies
1d1h

Exactly. Many programmers don’t want to worry about edge cases, and cross platform GUI frameworks are essentially coding an “oops all edge cases” project.

supportengineer
5 replies
1d1h

Yes, as a longtime software developer people have been trying to solve this problem different ways my entire career. The closest we got was Java swing. And it works well enough for things like eclipse but for some reason, nobody wants to use it and they want to use things like Electron instead

smokel
2 replies
1d1h

Regarding the "for some reason": Java Swing (and JavaFX, and Windows Forms for that matter) all suffer from lack of integration with modern web browsers. It is near impossible to find a way to combine these model-view-controller based user interfaces with the DOM in a reasonable way.

Horrible as it is, web browsers have managed to provide a common platform for user interface delivery. The browser wars have been fierce, and getting this foot between the door has cost several companies a lot of money. This technological monopoly is far from optimal, but I fear that we are stuck with it, as we are with QWERTY keyboards, USB thumb drives that must be unmounted manually, and the hopeless misery that is Bluetooth.

skydhash
1 replies
16h45m

That’s because companies want you tethered to their servers. There are plenty good native apps that doesn’t require to have half GB to run them. Most SaaS coul be native if they want too, but hey, you have a 32GB laptop, right? And we want all your data anyway. Here is our Electron app!

smokel
0 replies
8h47m

> That’s because companies want you tethered to their servers.

It is slightly more nuanced, IMHO. For enterprise software it actually makes sense to use browser based software, because it saves the IT department a lot of hassle with local installations and version management.

wiseowise
1 replies
1d

Isn’t Eclipse written using SWT?

jasomill
0 replies
20h59m

Yes. In fact, IBM created SWT to implement Eclipse.

Ghidra is an example of a large, cross-platform application I use regularly that does use Swing. While it's a terrific reverse engineering tool, its UI leaves at least a little to be desired. Examples, not necessarily Swing's fault:

• Non-native text controls. This is particularly painful on macOS, where Ghidra text controls don't provide access to useful system services (Web search, dictionary look-up, translation, spell check, text-to-speech, sharing, … [it's an extensible list]) and don't honor custom key bindings defined in ~/Library/KeyBindings/DefaultKeyBinding.dict.

• Non-native file open/save and print/page setup dialog boxes.

• Non-native font selection with very limited options: can't choose weights other than standard or bold, can't choose widths (condensed, expanded, etc.), can't choose OpenType stylistic alternatives, etc.

• Per-window menu bars even on platforms where global menu bars are an option (KDE) or standard (macOS). As a consequence, no menu bar search or ability to remap menu item keyboard shortcuts on macOS.

• Other fiddly control differences. For example, on macOS, Option+Right/Left Arrow on a tree view node typically expands/collapses all descendants. On Ghidra, Option+Left Arrow collapses all, but Option+Right Arrow expands only children, with an additional level expanded for each subsequent Option+Right Arrow keypress. While Ghidra's behavior is arguably more useful, it's still inconsistent with platform norms.

• High DPI scaling inconsistent across platforms (works fine by default on macOS, requires fiddling on Windows and Linux).

• No integration with system-provided dark modes.

• No out-of-box support for installation as a native GUI application (macOS app, Windows Start Menu shortcut, Linux .desktop file). To be fair, with the arguable exception of Mac apps, this is out of scope for a GUI toolkit, and I suspect most people in Ghidra's target audience have no problem hand rolling a solution.

gonzo41
4 replies
1d3h

I'm still super disappointed that javafx died.

winrid
0 replies
1d

It's not dead. I just launched an app this year with it. Users love it.

mark38848
0 replies
1d2h

Anything related to Java dying is a win in my book

throwaway894345
3 replies
1d4h

I’m not sure whether those toolkits abstracted over native GUI interfaces or whether they attempted to recreate a native look and feel or whether they attempted to provide their own look and feel across platforms, but in any case the problem isn’t languages and compilers, it’s that the expectations for a GUI toolkit are dramatically greater now than then. Here are a few things that are (I think) expected from GUI toolkits today, but not 30 years ago:

* Hardware acceleration (in particular abstracting over metal, opengl, direct x, vulkan, etc)

* More complex layouts

* Animations

* Much hateful text rendering (e.g., right-to-left language support): https://faultlore.com/blah/text-hates-you/

* Accessibility

And if you want to emulate a native experience, getting keyboard shortcuts, focus behavior, and a billion other details correct is nearly impossible.

And by the way, today we have web engines that take care of most of these things for free and a huge pool of people who know how to build for them, so it’s often easier to leverage that capability than to essentially reinvent them.

And if people can contain their knee-jerk anti-electron reaction for a moment, I think that’s a pretty reasonable approach. I would really like to see something like an unlocked ChromeOS where the browser is the native interface, but unlike electron, we don’t ship a web browser with each app. Especially as webasm takes form, I could see this as a more compelling solution for cross-platform graphics with multi-language support than cross-language bindings or by trying to maintain a toolkit per language while trying to maintain some illusion of a consistent experience.

jwells89
2 replies
1d3h

In some ways, expectations for UI toolkits have dropped too, though. Practically no UI toolkits created in the past 5-10 years come with a row recycling tableview/datagrid widget (table with column headers, sort by column, etc) for example, which used to be table stakes (which is why they’re present in Win32, MFC, AppKit, GTK, and Qt among others of the old guard). New toolkits that lacked a tableview would not have been taken seriously back then.

This has been a major blocker for my adoption of newer toolkits. I understand that it’s a result of mobile UI trends dominating the space, but that’s not helpful when I’m looking to build useful desktop apps, for which these widgets are crucial. Relying on third party libraries to fill these gaps (if they even exist) isn’t appealing either, adding yet another dependency to the pile and making a major part of my app subject to likely eventual abandonment by the library’s dev.

euroderf
1 replies
1d

Tableview?

Try a Treeview. For Go UI kits you can count the treeviews on one hand.

jwells89
0 replies
23h34m

Yep that’s another one that’s frequently missing. Basically any scrollable displays of data that aren’t a simple single column list or a grid are entirely absent in newer UI toolkits.

KronisLV
2 replies
1d2h

I really think that the Lazarus Component Library took the right approach: https://en.wikipedia.org/wiki/Lazarus_Component_Library

I wonder why the idea of widgetsets never really went anywhere: https://en.wikipedia.org/wiki/Widgetset

You could take a program that says you need a button in the window and it would make one for you on Qt, GTK or whatever else was supported, on any platform that you were compiling for.

We might as well have gone a step further: your programming language --> UI toolkit bindings for your language --> programming language independent GUI toolkit --> widgetsets for GTK, Qt, WPF, Win32 or whatever else --> executable for that specific platform

With that many layers of abstraction it's likely that we'd get the lowest common denominators for all functionality across platforms, but at least it would run better than web technology does, with the accessibility and platform look & feel you'd expect.

Of course, for whatever reason, seems like nobody wanted to undertake the borderline crazy effort of creating something like that, something foundational for others to build upon, so that's why we get super fragmented frameworks that are bound to specific languages nowadays and each of them have to reinvent a wheel a lot.

Either way, FreePascal/Lazarus were pretty amazing for RAD: https://en.wikipedia.org/wiki/Lazarus_(software) except that the community and ecosystem isn't exactly getting bigger.

supportengineer
1 replies
1d1h

Now there is a generation of software developers who grew up with web technology, and they aren’t old enough to recall the days of native apps - they don’t know any way other than HTML.

skydhash
0 replies
16h56m

Lol. One of good cross platform example is Calibre [1], built with Python and Qt. And it’s the only one I carried with me from Windows XP/10 to macOS, through Linux. Another is Sublime Text.

[1]: https://calibre-ebook.com/

amelius
1 replies
1d3h

We have HTML now, which is a great advancement. Don't forget about that.

zackbrown
0 replies
1d3h

HTML was a huge advancement, but it is likely a local maximum.

The HTML / CSS stack comes with significant ergonomic hurdles (layout / positioning / "creative fidelity") and performance hurdles (inescapable GC pauses, constant overhead of constraint-solving layout system, DOM overhead in general.)

Can we do better? IMO the future GUI lingua franca is deeply inspired by HTML and will stand on the shoulders of that giant, but will:

  - Build to LLVM native apps as well as websites
  - Include React-style templating as a foundational concern
  - Be fundamentally designed for visual building (think of the ergonomic differences between Webflow & Figma — if "an HTML" existed that "a Figma" could read & write natively, building front-ends would take a quantum leap)
WebAssembly makes all of this possible while still extending the Web and browser ecosystems.

shikaan
18 replies
1d8h

Go newbie here. Can anybody elaborate on this piece of the docs?

""" You might be thinking that it would be more usual to have an ops.Add(ColorOp{Color: red}) method instead of using op.ColorOp{Color: red}.Add(ops). It’s like this so that the Add method doesn’t have to take an interface-typed argument, which would often require an allocation to call. This is a key aspect of Gio’s “zero allocation” design. """

Why would there be an allocation? Of what? How are we saving it?

ainar-g
6 replies
1d7h

Whenever you do:

  v := interfaceType(concreteTypeValue)
in Go, what you're actually doing on a lower level is:

  dataPtr := &concreteTypeValue
  typePtr := typeData[concreteType]()
  v := interfaceData{
          data: dataPtr,
          typ: typePtr,
  }
The first line here is the allocation, since (at least, the way I recall the rule) in Go pointers never point to values on the stack, so concreteTypeValue must be allocated on the heap. The rule about pointers not pointing to the stack is there to make it easier for goroutine stacks to grow dynamically.

See https://go.dev/doc/faq#stack_or_heap.

foldr
5 replies
1d7h

in Go pointers never point to values on the stack

This is only the case for pointers that the compiler can't prove not to escape:

In the current compilers, if a variable has its address taken, that variable is a candidate for allocation on the heap. However, a basic escape analysis recognizes some cases when such variables will not live past the return from the function and can reside on the stack.
ainar-g
4 replies
1d7h

That could be true, but I've done a few optimizations of allocations in Go code, and I don't recall pointers to stack values ever being optimized (unless the entire branch is removed, of course). If anyone could provide an example of the code that does pointer operations yet doesn't cause allocations, I'd appreciate it!

ainar-g
2 replies
1d5h

Ah, so extremely localized uses of pointers, got it, thanks.

kevindamm
5 replies
1d7h

This has to do with how Go handles dynamic typing via interfaces and how structs fit into that.

When a function takes an interface type as an argument, and you pass a pure struct to it, it creates a wrapper around it (this is the allocation referred to in your quote) which is simply a pair of pointers, one being a type/vtable pointer and the other being a pointer to the struct's data.

Doing it this way allows code to do run-time type inference as well as allow interface extension implicitly (that is, implementing an interface is done by implementing its methods, and you don't have to explicitly type it like ByteReader extends Reader"). Since you only pay this cost if you use it, a lot of fast-path code will use structs exclusively if it can.

DougBTX
4 replies
1d6h

How do generics change this? Can a type bound on a generic work like a static interface implementation specification, and recover the cost of wrapping the struct?

erik_seaberg
3 replies
21h46m

You can declare generic structs and generic functions, and get monomorphized copies (not erased to "any") of each function for all concrete types used. You can't look them up by reflection. You can't declare generic methods, and still can't overload methods by type.

paullgdc
1 replies
20h47m

get monomorphized copies (not erased to "any") of each function for all concrete types used

That's not exactly true. You get one concrete function for all generic pointer types for instance. Generic functions take a hidden paramater called a dictionnary, which is fairly similar to vtable, since it contains type information and pointers for all methods of the generic type that the function calls.

So methods on generic types are still performed through an indirection.

https://github.com/golang/proposal/blob/master/design/generi...

erik_seaberg
0 replies
20h15m

Thanks, had not seen that before. It's odd that they came close to reimplementing method dispatch for builtin types, but didn't surface it for developers.

shikaan
0 replies
1d2h

Thanks all (:

neonsunset
0 replies
1d7h

Heh. Go just doesn’t let you write zero-cost generic abstractions the way C# does.

foldr
0 replies
1d7h

On the first approach ColorOp{Color: red} would have to be boxed and thus heap allocated. This is because ops.Add in general would receive a (fat) pointer to a value implementing a particular interface rather than a value of concrete type.

(The sibling comment written at the same time has a more detailed explanation of the 'fat' part.)

Someone
0 replies
2h33m

You might be thinking that it would be more usual to have an ops.Add(ColorOp{Color: red}) method instead of using op.ColorOp{Color: red}.Add(ops)

Others answered your question, but on a different subject: I find that weird to read. To me

  op.ColorOp{Color: red}.Add(ops)
reads like “add ops to the result of op.ColorOp{Color: red}. I would name that function AddTo:

  op.ColorOp{Color: red}.AddTo(ops)
Still unconventional, but at least it messages that the function argument gets modified.

diskdance
11 replies
1d4h

Seemingly it's using a <canvas> to render everything just like Flutter on Web, which is known to have problems with accessibility and feel non-native.

afavour
5 replies
1d4h

I’m curious if anyone has a variant of this idea where an invisible DOM lives alongside the canvas for accessibility reasons. It should work but I imagine it would also take a lot of work.

mwcampbell
1 replies
1d4h

This is how Flutter for web implements accessibility. It's been a while since I checked, but last time I tried using a Flutter app on the web with a screen reader, there were problems. I don't remember specifics.

serial_dev
0 replies
1d3h

Flutter on Web is still mainly not accessible when it comes to screen readers, despite what anyone wants to make you believe.

I checked it last a couple of weeks ago on my Android phone, and the result was so poor, I didn't check with other platforms.

You need to "opt in" to accessibility as a user, so in the beginning you have one button visible to screen readers, then your screen reader sees that single button, then you need to "double tap to activate" to make the rest of the document screen readable.

Then, somehow they made a funky screen reader voice read stuff out loud, not my system's voice, with all the awkwardness and issues that come with it.

On lists, it only recognized the items that were on screen, if you had to "scroll", you are out of luck.

Now, I'm sure someone will come and tell me how I'm holding it wrong, but somehow, every website and even Flutter on mobile got the accessibility mainly right by default, on Flutter web the accessibility situation is very poor.

zdragnar
0 replies
16h55m

The canvas element allows children specifically for this purpose, iirc.

Edit: unless you're doing something like flutter where your goal is to escape the DOM/JS paradigm in your code entirely, the fallback DOM nodes don't tend to be implemented too often.

The biggest reason is that canvas is for things with interactive/consumptive patterns that don't work well without vision.

Cute animations, 3d explorers and configurators, that sort of thing.

For users who rely on screen readers, they are better served by a DOM and interactive patterns that are not strictly recreating the canvas.

As an example, canvas based animations might have a fallback equivalent to an alt attribute on an image. A 3d explorer or configurator might be represented in DOM as a multi step form with verbose descriptions- no need to recreate drag and drop, camera controls, or anything else.

So, if you're not automating it like flutter is (and even if you are) what you really need to do is effectively an entirely alternate UX for screen reading users... Trying to get your product team to budget that is difficult despite being a Good Thing to do.

zackbrown
0 replies
1d3h

Check out the approach that Pax is taking.[0]

Pax renders vector graphics to canvas layers and composites + clips + occludes native elements (web DOM nodes, iOS SwiftUI Text elements, etc.) in the same space to make a cohesive scene.

This solves accessibility and SEO, as well as dramatically reducing runtime size (~100KB WASM network footprint) because text rendering and atomic native UI elements don't need to be reinvented.

To my knowledge we're the only ones taking this particular approach so far (I'm on the team behind Pax) but it works quite well. Yes it was a lot of work.

[0] see pax.dev or check out a simple example: https://static.pax.dev/space-game/ ; source code for space game in examples on github https://www.github.com/paxengine/pax

mort96
2 replies
1d4h

I mean it's not primarily a web app framework, it's a native GUI toolkit which has a web back-end.

Longhanks
1 replies
1d1h

It isn't native on any other platform either.

mort96
0 replies
21h30m

I used "native" as opposed to "web" (think "native code"), not as in "uses Cocoa on macOS". I should've been more precise.

brirec
0 replies
20h28m

Can’t even copy or paste at all on an iPhone.

abroadwin
0 replies
1d3h

Definitely doesn't feel native or accessible on web. Can't tab between radio buttons. On macOS CMD+A doesn't select all text field text (CTRL+A does).

DrDroop
10 replies
1d7h

Experience report: Impossible to write any serious complex application in this. Lacks components for basic things everyone gets for free on other platforms, things like video, maps or rich text components. Nor does if offer any clear easy path to add them yourself. Breaking API changes every few months. No way to theme something. Immediate mode graphics are great until you need to start managing some complex state, then you are forced to implement your own retainer mode graphics. Again it reintroduces problems that have been solved a long time ago. Very fancy renderer based on piet-gpu that only takes control points of a bezier curve as input and tessellates everything from that. Cool concept, but try drawing a real circle with that, and some some approximation with 4 bezier curves. Wasm is not more then a proof of concept that won't be production ready without years of engineering by compile team. Overall nice for Go developers that wanna do some simple UI with lists and input fields.

mort96
8 replies
1d4h

Breaking API changes every few months.

I find this to be the case with a depressing amount of Google code. They do not seem to have a culture which values not breaking their users' code.

mdhb
3 replies
1d

This isn’t true in Flutter. They literally bake into the CLI with each release which will automatically identify and upgrade any parts in your application using old APIs without any intervention required. It’s literally the opposite of what you’re describing here.

https://docs.flutter.dev/tools/flutter-fix

mort96
2 replies
23h54m

What you described is Google breaking your code constantly but also giving you a tool to automatically fix the code they broke, so it fits well within the general philosophy of not taking breaking changes seriously.

It sounds like the tool might make the specific case of flutter version upgrades easier though, if the tool works well, so that's nice. Most Google software doesn't come with similar tools.

mdhb
1 replies
23h35m

There is nothing about that that allows you to come to a good faith conclusion of “doesn’t take breaking changes seriously” when they literally do all of the work for you.

mort96
0 replies
23h29m

You're right. I should've said they have no qualms about introducing breaking changes.

Philip-J-Fry
2 replies
1d3h

Gio isn't made by Google

kernal
1 replies
15h5m

Go was invented at Google by Rob Pike, Ken Thomson, and Robert Griesemer.
kernal
0 replies
12h2m

My bad, you said Gio.

suby
0 replies
1d

It's even a core point for Carbon, their hopeful C++ replacement

Under language goals on their readme,

We also have explicit non-goals for Carbon, notably including:

* A stable application binary interface (ABI) for the entire language and library

* Perfect backwards or forwards compatibility

There's also this blurb

Our goals are focused on migration from one version of Carbon to the next rather than compatibility between them. This is rooted in our experience with evolving software over time more generally and a live-at-head model. Any transition, whether based on backward compatibility or a migration plan, will require some manual intervention despite our best efforts, due to Hyrum's Law, and so we should acknowledge that upgrades require active migrations.

https://github.com/carbon-language/carbon-lang/blob/trunk/do...

neonsunset
0 replies
1d7h

If you care about WASM, Uno Platform has decent support for it, there’s also AvaloniaUI and both are stable at this point with relatively rich control collections and libraries.

andreygrehov
7 replies
1d3h

Why do all these cross-platform GUIs look like they were designed 50 years ago?

paulddraper
6 replies
1d3h

I...would like to know what you were using in 1974 that looked like that.

andreygrehov
5 replies
1d3h

Heh. The "50 years ago" part was an intentional stretch to add more weight to how disappointed I am. But seriously, the first demo they presented is an immediate rejection.

tazjin
2 replies
1d

The first demo is a Webassembly thing that looks like any generic web thing. The next one is a cryptocurrency app that seems to have a "modern" design.

The other ones (gotraceui, sointu) seem like they might be what you're talking about. I can see how they might be scary to someone used to "modern" UIs because their information density is much higher.

Personally I'd prefer if more people treated computers like a tool, and not some kind of art installation.

andreygrehov
1 replies
23h27m

I was referring to the Webassembly one. Looks like the design was largely inspired by the Material Design created by Google. Material Design is a massive failure and nobody should use it these days.

The cryptocurrency app looks good.

The gotraceui and sointu are actually decent. They are niche tools and look fine to me.

tazjin
0 replies
23h25m

Material design always looked like a total mess to me.

anthk
1 replies
1d2h

Smalltalk wasn't that far ;)

anon-3988
6 replies
1d7h

How does this compare with Fyne?

mappu
5 replies
1d7h

They both owner-draw every widget themselves (not using platform native widgets).

Gio is pure Go, Fyne is cgo.

Gio is immediate-mode, Fyne is retained-mode.

Flamewar starts here: I don't know why anyone would seriously choose an immediate mode GUI toolkit. When you receive an event, in immediate mode you have to recreate the whole world, then the toolkit has to then either rerender the world from scratch, or else diff the world against a clone on the heap, and rerender dirty regions. These kind of toolkits "advertise" hitting 60fps rerender speed as if that was impressive. In retained mode you merely don't respond to events you don't need to, the framebuffer doesn't need modification at all, and getting only 60fps updates would be embarassingly slow.

I understand the appeal of integrating e.g. Dear Imgui into your game's render loop if you're already re-rendering the whole viewport. But for desktop/mobile applications where the platform has a retained framebuffer, it seems like a deliberate deoptimisation.

ramon156
1 replies
1d6h

One positive side of immediate mode is that the code becomes a lot more straight forward. You only see that loop function, so it's very nice if you need a POC, or if it's going to be ran on embedded.

mappu
0 replies
18h12m

Here's some pseudocode for argument's sake: http://paste.debian.net/1317369

I don't think the immediate-mode code is really more straightforward. Retained mode looks just as simple and only has that one same function with the same 5 basic SLoC, only

- (A) the ui library has to do less work at runtime, resulting in a more responsive app (as per parent comment);

- (B) i was forced to reorder the component instantiation. In immediate mode, the counter's label depends on the button's state, whereas in retained mode, the button update callback depends on the counter instead; and

- (C) immediate mode only needed one sprintf instead of two since the initialization and update logic is unified. You can combine them in retained mode with a helper function or closure (and in real-world apps you would); in this trivial case this increases the SLoC but in real-world cases it reduces it.

metaltyphoon
1 replies
1d5h

Gio is pure Go

7% C is not pure Go.

tredre3
0 replies
1d2h

There is hardly any real C code in Gio, it's just bindings for the platforms' APIs (X11, Wayland, GL).

Somehow, they managed to avoid requiring CGO on Windows so it's 100% Go there.

pants2
0 replies
1d3h

I recently wrote a little document previewer in Fyne. It's a great experience and super easy to build simple GUIs, however Fyne struggled with a few pages of text (slow scrolling and resizing). I'll have to try Gio.

w1nst0nsm1th
4 replies
1d7h

Blazor is cross-platform, in combo with MAUI.NET

lakomen
3 replies
1d5h

I didn't downvote.

AFAIK it's not supporting Linux as a target platform. Correct me if I'm wrong.

andsoitis
2 replies
1d4h

.NET MAUI supported platforms:

* Android 5.0 (API 21) or higher is required.

* iOS 11 or higher is required

* macOS 10.15 or higher, using Mac Catalyst

* Windows 11 and Windows 10 version 1809 or higher

While Linux isn't supported, that is also not a typically significant market for GUI apps.

https://learn.microsoft.com/en-us/dotnet/maui/supported-plat...

bornfreddy
1 replies
1d3h

However Linux has a non-negligible share among platforms that developers use (as a daily driver). To me, as a Go developer, this library is dead on arrival. It would take extraordinary circumstances to consider it for an app (even in business setting).

neonsunset
0 replies
1d2h

For Linux, there are Avalonia, Uno Platform and Gir.Core (rich GObject and GTK4 bindings).

The point of MAUI is to be a successor to Xamarin, for which the primary target are mobile devices, by far the largest market niche.

999900000999
4 replies
1d2h

I built a small app in Go using Fyne.

Never again. Both Gio and Fyne lack tons of polish and features Flutter provides.

I built my core logic in Golang, and then decided to wrap it in an Android app. The GUI feels like it came out of 2003 with limited ways to fix it.

saganus
1 replies
1d1h

Sounds interesting. How did you wrap it in an Android app if you could elaborate?

999900000999
0 replies
1d1h

Simple, I basically wrote a script to figure out probabilities for gambling ( I won't open source it since I don't want someone angry at me when they lose money). Then you basically have the UI layer call the script.

It's really hacked together, but it works.

PhilippGille
1 replies
1d1h

A different option is Wails [1], which allows you to write all logic in Go, and the UI in HTML (with any or no web framework). It's like Electron but lighter because it doesn't ship Chrome but uses the system's web viewer instead.

[1] https://github.com/wailsapp/wails

buildbuildbuild
0 replies
1d

Wails is great. Also, see Tauri for a similar lightweight approach in the Rust ecosystem.

oefrha
2 replies
1d6h

It's a good sign that unlike fyne, this library passed the very first test I threw at it: rendering some CJK text. Fyne can't do that unless you give it one custom font to render everything in — well, good luck finding one satisfactory font encompassing all commonly used scripts around the world, not to mention emojis. Which means fyne is immediately dead to me whenever I'm building anything with a remote chance of user-generated/web content and/or localization.

maccard
1 replies
1d5h

Noto sans is pretty good in this regard.

oefrha
0 replies
1d5h

Noto Sans isn't limited to Latin — it supports Cyrillic and Greek as well — but immediately fails my CJK test. Or Arabic, or various other scripts used by half of the world.

flohofwoe
2 replies
1d6h

Interesting that the WASM demo on the front page just render a black rectangle where the text is supposed to be on my fairly vanilla Windows 10 PC with Chrome (it rendered fine in Chrome on my Android phone).

joezydeco
0 replies
1d1h

It wasn't just me. Whew. It also ran incredibly slow.

bwat49
0 replies
1d5h

same here with edge on windows 11

luismedel
1 replies
23h49m

Not about Gio UI but related.

I'm really enjoying the conversation around UI toolkits here. But I think we're all missing the elephant in the room and it's that we already had (have?) a superb toolkit and development model in the Visual Basic (later Windows Forms) era and nothing really manages to replicate that experience nowadays.

Microsoft destroyed it when they tried to push WPF and later shenanigans, only to realize it was a mistake years later.

I can't understand why we all, as a sector, agree about standards being a good thing, even if some are only de facto, and never agreed to maintain that really simple model.

I remember Mono tried to bring that to all platforms and everybody ignored/smashed them because "it's Microsoft".

Edit: typo

skydhash
0 replies
16h40m

I remember Mono tried to bring that to all platforms and everybody ignored/smashed them because "it's Microsoft".

Microsoft destroyed it when they tried to[…] only to realize it was a mistake years later.

Answer is right there.

okasaki
0 replies
1d4h

The demo doesn't work for me. I see some buttons but mostly it's all black. Chromium on Win 11.

glass-z13
0 replies
1d4h

Yet non of the GUI libraries/frameworks for GO support drag/drop file to get the real path

cabalamat
0 replies
1d1h

I note form the demo that there's a "Flat" button that looks like normal text. This is a mis-feature and should be removed; controls should look different from things you can't interact with.

andsoitis
0 replies
1d4h

doesn't appear to support Unicode.