[HN Gopher] Show HN: Spot - Simple, cross-platform, reactive des...
___________________________________________________________________
Show HN: Spot - Simple, cross-platform, reactive desktop GUI
toolkit for Go
Hi HN, I'm excited to share Spot, a simple, cross-platform, React-
like GUI library for Go. It is just a few days old and has lots of
missing features but I'm happy with the results so far, and looking
for some design feedback. Spot is designed to be easy to use and
provide a consistent API across different platforms (mainly Mac &
Linux). It's inspired by React, but written in Go, aiming to
combine the best of both worlds: the easy tooling & performance of
Go with a modern, reactive approach to UI development. Key
features: - Cross-platform: Leveraging FLTK[1] & Cocoa[2], Spot
works on Mac, Linux, and the BSDs with plans for native Windows
support in the future. - Reactive UI: Adopts a React-like model
for building UIs, making it intuitive for those familiar with
reactive frameworks. - Traditional, native widget set: Utilizes
native widgets where available to provide a more traditional look
and feel. Why I built it: I was searching for a cross-platform
GUI toolkit for Go that had a more traditional appearance, and none
of the existing options quite met my needs. I then started playing
with Gocoa and go-fltk and suddenly I worked on an experiment to
see how challenging it would be to build something like React in
Go, and it kinda evolved into Spot. -\\_(tsu)_/- In 2024, is there
a still place for classic desktop GUIs--even with a modern spin?
I'd love to hear your thoughts, feedback, and any suggestions for
improvement. Also, contributions are very welcome. Thank you for
checking it out! [1] https://github.com/pwiecz/go-fltk [2]
https://github.com/roblillack/gocoa
Author : da_rob
Score : 289 points
Date : 2024-05-24 19:19 UTC (1 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| ASalazarMX wrote:
| I don't know how to take this in. On one side, it's great to have
| a cross-platform GUI toolkit that's easy to use; on the other
| side, it feels like a React-like UI is contrary to the spirit of
| simplicity and resource efficiency of Go.
|
| I'm sure it has its perfect use cases, though.
| da_rob wrote:
| While I agree, that the virtual widget tree has a certain
| overhead, the typical desktop app you would create with Spot
| probably does not have 1000s of components--more like ten to
| twenty probably. Compare that to the immediate mode GUIs that
| currently are en vogue, that re-render all controls all the
| time.
|
| Spot does not have any optimizations regarding render
| performance at the moment and it might never be necessary to
| add them.
|
| On the other hand, due to the reactive programming model, I
| really like how state management get a lot clearer--especially
| when working with multiple goroutines.
| ygnasygnoimqwb wrote:
| > runtime.LockOSThread()
|
| > https://github.com/roblillack/spot/blob/main/ui/init_fltk.go...
|
| Does this imply GOMAXPROCS needs to be set to at least 2?
| da_rob wrote:
| No, it just means that the main goroutine should not be moved
| onto another OS thread to ensure that it is always the same OS
| thread which will run UI updates.
|
| This is necessary for most UI libraries and in Spot's case
| implemented for both the FLTK and the Cocoa backend.
| scosman wrote:
| Cool!
|
| What does building for cross platform look like? Would love if
| there was a command that produced my MacOs .app and Windows exe
| without me having to dive into package
| management/containers/signing headaches per platform.
| da_rob wrote:
| The backends (FLTK/Gocoa) are using CGo, which currently does
| not support cross-compiling as far as I know.
|
| So you still need to have a build pipeline with multiple
| operating systems, signing/notarization tools, etc. :(
| scosman wrote:
| Too bad.
|
| I swear half the electron apps use it for ease of Xplatform
| build.
|
| I'd love something like this for giving my CLIs UIs.
| mappu wrote:
| You can cross-compile Cgo, you "just" need a C compiler and
| linker that works for the target platform. osxcross, xgo have
| some or maybe you can set CC=zig cc.
|
| For macOS you need signing/notarization tools either when
| building natively or when cross-compiling, it's not any
| different. `rcodesign` has made this process much easier in
| recent years.
| apitman wrote:
| +1 for `CC=zig cc`. Feels like magic
| felipefar wrote:
| That'd be amazing not only for go apps but for software built
| on other languages as well. I'd pay for a good, straightforward
| build packing + crash reporting + autoupdater solution for my
| apps.
| allanrbo wrote:
| Was looking for something like this some years back. Though I
| wanted Windows support too. Ended up switching to C++ to use
| wxWidgets, giving me small self contained binaries.
| da_rob wrote:
| Big fan of WxWindows, I'm just too invested into Go these days.
| :)
|
| Self-contained Spot "Hello World" is 2.3MiB on my Mac. Not
| pretty, but works for me.
| ofrzeta wrote:
| So you didn't like to continue on that?
| https://github.com/dontpanic92/wxGo
| da_rob wrote:
| Geez, look at the build instructions! It all went downhill
| when they switched from Motif to GTK.
| mappu wrote:
| go-fltk does build and run on Windows, pretty well actually.
|
| For a native toolkit, I was impressed to see FLTK supports
| Ctrl-+ and Ctrl+- to zoom the entire application like a
| browser. And https://github.com/fltk-rs/fltk-theme?tab=readme-
| ov-file#wid... really improved my impression of how "native"
| FLTK can be made to look.
|
| On a related note, I discovered GoVCL https://z-kit.cc/en/
| recently and am interested to try it out.
| zerr wrote:
| There is wxGo, but sadly the project is not maintained.
| jakjak123 wrote:
| Very cool idea!
|
| If someone implements GTK I would absolutely use it, its just
| fltk is no fun in Linux world
| Heliodex wrote:
| If only I had known about this (or judging by commit history, if
| it existed) ~3 weeks ago. I've been saying for ages that either
| React ported to Go or a React-like framework for Go would be an
| incredible development experience, so this looks perfect (I used
| to be a big hater of React.js until I was enlightened by
| React.lua).
| apitman wrote:
| Don't leave us hanging! What did you use instead 3 weeks ago?
| Heliodex wrote:
| Wails <https://wails.io>. I wanted to use Go but wasn't as
| familiar with native UI as with HTML/CSS/JS, I tried out most
| of the other popular Go UI frameworks too though they didn't
| feel as comfortable to use as Spot's React-like model.
|
| Wails is still pretty epic as well though.
| parlortricks wrote:
| oh this looks great
| rkwz wrote:
| I had the same problem - really liked the way I used to do
| component composition in React, it was hard to go back.
|
| Eventually found a way to do something similar using just the
| standard Go html/template.
|
| I've written about the implementation here:
|
| https://www.sheshbabu.com/posts/react-like-composition-using...
| biomcgary wrote:
| This a great write-up and similar to an approach that I
| stumbled upon a few years ago. Have you thought about HTMXing
| this approach to get away from full page renders?
| heywire wrote:
| I'll have to give this a look! I've been looking for a simple way
| to use Go to write an internal development tool which is
| basically just a form with some buttons and text fields. I tried
| Gio, but had a hard time with wrapping my head around it. Right
| now I'm using wails and like it much better. This looks
| interesting and worth a look!
| da_rob wrote:
| Perfect use-case, IMHO! Looking forward to hear your thoughts
| ocne you tried it.
| getcrunk wrote:
| Fltk supports windows. Will you be using another solution and
| that's why u don't support windows yet?
| da_rob wrote:
| Given the right C compiler and everything, Spot should work
| without changes on Windows (and select the FLTK) backend.
|
| My (low prio, though) goal is to implement a Win32-based
| backend, though, the first step is done:
| https://github.com/roblillack/spot/pull/4
| KingOfCoders wrote:
| I applaud your effort, but cross plattform with no Windows
| support?
| jppittma wrote:
| Here's a nickel kid. Get yourself a better computer.
| KingOfCoders wrote:
| Thanks, I'd wish I could get my G4 Cube back.
| poisonborz wrote:
| Why is platform shaming tolerated around here
| IshKebab wrote:
| Oh you mean one that can sleep reliably and has battery life
| of more than 2 hours?
| atlas_hugged wrote:
| Use WSL
| RobotToaster wrote:
| It looks like it just uses FLTK on windows, they just don't
| have native support on it.
| felipefar wrote:
| I'm curious to hear your take on this: what's the advantage of
| following the virtual control tree approach compared to instead
| updating directly the controls that are displayed to the user?
| da_rob wrote:
| For complex scenarios (i.e. the user interacting with the UI
| while there are some long-running processes in the backround
| doing this, too), managing the state quickly gets unwiedly: You
| need to write callback code everywhere that carefully has to
| inspect the current status of all other activities and might
| then updates 10s of widgets accordingly.
|
| With the reactive approach you are able to write a single
| rendering function that describes the interface for any given
| state and the framework takes care of the rest (when to call
| that function, what "input" to give it).
|
| It's just way easier to wrap my head around this and after
| working with React it is hard to go back. Hence the experiment
| to see if something comparable could be done in Go.
| felipefar wrote:
| I'm already convinced of the benefit of declarative GUIs over
| imperative ones. To be clearer, what I mean by declarative
| GUIs is ones where I can specify that UI elements should be
| bound to certain values in the memory of my program, so that
| they don't have to be changed explicitly by imperative code.
| Ex.:
|
| TextBox { Text: app.currentUser.name }
|
| Instead of having to call setText on that TextBox.
|
| What I'm still missing is why it has to involve a virtual
| tree being maintained and synchronized with the real GUI
| tree. The UI engine could implement the above binding by
| instantiating for the user a callback trigerred when the
| bound property changes and changing precisely the value
| currently shown on the screen. Hence, the UI engine is in
| charge of the callbacks, which keeps the user unburdened by
| callbacks.
| da_rob wrote:
| The virtual component tree is needed as there is no 1:1
| mapping of components to widgets.
|
| Using the virtual tree, you are able to build components
| which dynamically change the rendered subtree based on the
| current state.
| iainmerrick wrote:
| SolidJS works pretty much as you describe, and it's great.
| It feels like the best bits of React, but object lifetimes
| and re-rendering and the real UI behavior are all much
| easier to understand.
|
| (Or at least, to paraphrase Joseph Heller, "it's intuitive
| once you get your head around it")
| jdthedisciple wrote:
| If I'm not mistaken what you describe is pretty much
| exactly the approach in .NET app development (WPF, MAUI,
| ...) with C# for the logic and XAML for declarative UI
| including Binding and it works well and performantly so.
| dweymouth wrote:
| This is exactly how the data binding APIs in Fyne (another
| Go GUI toolkit) work. And it's also an optional feature, so
| if you want to handle things by registering callbacks and
| calling setters yourself you can do that too.
| lenkite wrote:
| Thanks for making this library, but IMHO these are distinct
| concerns. One can leverage a state machine or an ECS library
| for complex state management. Only basic data binding can be
| a framework capability if needed.
|
| The web had a lack of options for state management and hence
| React coupled the two.
| zem wrote:
| interesting that this uses fltk; I've seen very few language
| bindings to it
| andrewfromx wrote:
| Been using
|
| https://fyne.io/
|
| https://github.com/fyne-io/fyne
|
| for years but will check this out
|
| ( terminal but still great go guis:
|
| https://github.com/gizak/termui
|
| https://github.com/charmbracelet/bubbletea )
|
| Never used but should be in this list:
|
| https://gioui.org/
|
| https://mattn.github.io/go-gtk/
|
| https://github.com/lxn/walk
| bsimpson wrote:
| It's strange to see "inspired by Material Design," and then a
| bunch of controls that look nothing like Material.
| iamcalledrob wrote:
| I have been looking for something like this in Go for a while. I
| think there's a real opportunity for Go to provide a great
| developer experience for cross platform UI due to how simple the
| build process is. Speaking from experience, half the pain of
| cross platform development is managing build complexity, which Go
| basically eliminates.
|
| I'm curious how you'll end up solving for cross-platform layout
| when native controls have different intrinsic sizes per platform?
|
| This is something I haven't seen solved super well in cross
| platform toolkits.
|
| Wishing you luck though.
| kdma wrote:
| Just for curioristy why did you adopot a react-like model and not
| implement react-dom as projects like react native do?
| bsimpson wrote:
| React Native runs in JavaScript. This is in Go.
| sandreas wrote:
| [delayed]
___________________________________________________________________
(page generated 2024-05-25 23:01 UTC)