go-widgets
One widget tree, painted by Go, on every surface Go reaches. A native
window on X11, Wayland, macOS and Windows; a <canvas> in a browser tab; a
terminal; an Android APK. No C toolchain, no webview, no system widget set:
every module builds with CGO_ENABLED=0, and every pixel is drawn by the
toolkit.
w, err := window.Open(window.Config{Title: "Hello"})
if err != nil {
return err
}
defer w.Close()
box := toolkit.NewVBox()
box.Append(toolkit.NewLabel("Hello from go-widgets"))
box.Append(toolkit.NewButton("Click me", func() { /* ... */ }))
return w.Run(box) // an X11 or Wayland window, an NSWindow, a Win32 windowThat is
cmd/windowdemo,
shortened. The same box drawn in a browser, a terminal or a PNG is the same
code with a different surface underneath it.
Why one toolkit draws everything
A widget that calls the platform’s own button is as portable as the least
capable platform it targets, and looks different on each. go-widgets goes the
other way: a widget’s Draw only ever talks to a
painter.Painter, a handful of
primitives (fill a rectangle, stroke one, set a pixel, draw text). Whether
those calls become RGBA pixels or terminal cells is the back-end’s business,
not the widget’s.
What that costs is said plainly: no native look by default, and no free accessibility — the toolkit publishes its own accessibility tree to each platform. What it buys is one widget set, tested once, with the same behaviour everywhere, and a binary that cross-compiles from any machine to any of them.
Where to go next
| A first application | from app-template, or from a bare window |
| How a widget reaches the screen | the painter seam, the widget set, skins |
| The painter seam | the primitives every widget is drawn with |
| The toolkit | 160 widget types, themes, layouts, text, accessibility |
| Skins | a widget’s parts and states in a data file |
| State lives in a view-model | why widget fields are not assigned by hand |
| MVVM | observables, commands, binders, undo |
| The data spine | typed records, queries, a local or remote store |
| Where it paints | every back-end and how it is chosen |
| A native window | X11, Wayland, Cocoa, Win32, GTK4, Android, wasmbox, a browser tab |
| An application and its tray | lifecycle, appearance, a menu-bar icon |
| A browser tab | a plain <canvas>, or a wasmdesk window |
| A terminal | cell-native widgets and an interactive runner |
| Android | a real APK painted by a CGO-free process |
| Snapshots | a widget as an SVG or a PNG |
| Rules CI enforces | mvvmlint and bricolint |
| Modules | all nineteen, with their sources and references |
| Status | what is verified where, and what is not done |
Licence
BSD-3-Clause.
Created on by tannevaled
Modified on by tannevaled