πŸ“š gogpu/ui - Awesome Go Library for GUI

Go Gopher mascot for gogpu/ui

GPU-accelerated GUI toolkit with 22 widgets, 3 design systems (Material, Fluent, Cupertino), reactive signals, and zero CGO (part of [GoGPU](https://github.com/gogpu) ecosystem)

🏷️ GUI
πŸ“‚ GUI
⭐ 0 stars
View on GitHub πŸ”—

Detailed Description of gogpu/ui

GoGPU Logo

gogpu/ui

Enterprise-Grade GUI Toolkit for Go
Modern widgets, reactive state, GPU-accelerated rendering β€” zero CGO

CI Coverage Go Report Card Go Reference Version Go Version License Stars Discussions


Join the Discussion: Help shape the future of Go GUI! Share your ideas, report issues, and discuss features at our GitHub Discussions.


Overview

gogpu/ui is an enterprise-grade GUI toolkit for Go, designed for building:

  • IDEs (GoLand, VS Code class)
  • Design Tools (Photoshop, Figma class)
  • CAD Applications
  • Professional Dashboards
  • Chrome/Electron Replacement Apps

Key Differentiators

Featuregogpu/uiFyneGio
CGO-freeYesNoYes
WebGPU renderingYesOpenGLDirect GPU
Reactive stateSignalsBindingEvents
Layout engineFlexbox + GridCustomFlex
AccessibilityDay 1 (ARIA roles)LimitedLimited
Plugin systemYesNoNo

Screenshot

gogpu/ui Widget Demo

examples/hello β€” Checkboxes, Radio Buttons, ListView (1000 items), Material Design 3


Quick Start

Important: The gogpu ecosystem is pure Go with zero CGO. You must set CGO_ENABLED=0 (the Go default) β€” do not enable CGO.

The fastest way to get started is to clone and run one of the included examples:

git clone https://github.com/gogpu/ui.git
cd ui/examples/hello
go run .

Here is a minimal example showing the widget toolkit:

package main

import (
    "log"

    "github.com/gogpu/gg"
    _ "github.com/gogpu/gg/gpu"
    "github.com/gogpu/gg/integration/ggcanvas"
    "github.com/gogpu/gogpu"
    "github.com/gogpu/ui/app"
    "github.com/gogpu/ui/primitives"
    "github.com/gogpu/ui/render"
    "github.com/gogpu/ui/widget"
)

func main() {
    gogpuApp := gogpu.NewApp(gogpu.DefaultConfig().
        WithTitle("My App").
        WithSize(800, 600).
        WithContinuousRender(false)) // Event-driven: 0% CPU when idle

    uiApp := app.New(
        app.WithWindowProvider(gogpuApp),
        app.WithPlatformProvider(gogpuApp),
        app.WithEventSource(gogpuApp.EventSource()),
    )

    uiApp.SetRoot(
        primitives.Box(
            primitives.Text("Hello gogpu/ui!").
                FontSize(24).Bold().
                Color(widget.RGBA8(33, 33, 33, 255)),
            primitives.Text("Enterprise-grade GUI for Go").
                FontSize(16).
                Color(widget.RGBA8(100, 100, 100, 255)),
        ).Padding(24).Gap(12).Background(widget.RGBA8(255, 255, 255, 255)),
    )

    var canvas *ggcanvas.Canvas
    gogpuApp.OnDraw(func(dc *gogpu.Context) {
        w, h := dc.Width(), dc.Height()
        if canvas == nil {
            var err error
            canvas, err = ggcanvas.New(gogpuApp.GPUContextProvider(), w, h)
            if err != nil {
                log.Fatal(err)
            }
        }
        uiApp.Frame()
        sv := dc.SurfaceView()
        sw, sh := dc.SurfaceSize()
        gg.SetAcceleratorSurfaceTarget(sv, sw, sh)
        canvas.Draw(func(cc *gg.Context) {
            cc.SetRGBA(0.94, 0.94, 0.94, 1)
            cc.DrawRectangle(0, 0, float64(w), float64(h))
            cc.Fill()
            uiApp.Window().DrawTo(render.NewCanvas(cc, w, h))
        })
        _ = canvas.RenderDirect(sv, sw, sh)
    })
    gogpuApp.OnClose(func() { gg.CloseAccelerator() })

    if err := gogpuApp.Run(); err != nil {
        log.Fatal(err)
    }
}

Packages

Core (Phase 0)

PackageDescriptionCoverage
geometryPoint, Size, Rect, Constraints, Insets98.8%
eventMouseEvent, KeyEvent, WheelEvent, FocusEvent, Modifiers100%
widgetWidget, WidgetBase, Context, Canvas, Lifecycle (mount/unmount), SchedulerRef100%
internal/renderCanvas, SceneCanvas (tile-parallel), Renderer using gogpu/gg96.5%
internal/layoutFlex, Stack, Grid layout engines89.9%

MVP (Phase 1)

PackageDescriptionCoverage
a11yAccessibility: 35+ ARIA roles, Accessible interface, Tree, Announcer99.1%
stateReactive signals, Binding, Scheduler with push-based invalidation100%
primitivesBox, Text, Image widgets with fluent builder API94.4%
appWindow integration via gpucontext interfaces (dependency inversion)98.6%

Extensibility (Phase 1.5)

PackageDescriptionCoverage
layoutPublic layout API with custom algorithms89.5%
registryWidget factory registration for third-party widgets100%
themeTheme system with Extensions and Registry100%
pluginPlugin bundling with dependency resolution99.4%

Interactive Widgets (Phase 2 β€” Complete)

PackageDescriptionCoverage
cdkComponent Development Kit β€” Content[C] polymorphic pattern100%
core/buttonGeneric button with pluggable Painter, 4 variants, 3 sizes, signal bindings96%+
core/checkboxToggleable checkbox with checked/unchecked/indeterminate states, signal bindings96%+
core/radioMutually exclusive radio group with vertical/horizontal layout, signal bindings96%+
core/textfieldText input with cursor, selection, clipboard, validation, signal bindings96%+
core/sliderSlider: continuous/discrete, horizontal/vertical, drag+keyboard, signal bindings94.6%
core/dialogModal dialog: backdrop overlay, action buttons, focus trapping, Alert/Confirm96.9%
core/dropdownDropdown/select with overlay menu, keyboard navigation, signal bindings96%+
overlayOverlay/popup stack, container, position helper95%+
primitivesBox, Text, Image, RepaintBoundary (pixel caching + tile-parallel scene.Scene)94.4%
theme/material3Material Design 3 β€” theme (HCT color science) + 21 component painters97%+
focusKeyboard focus management with Tab/Shift+Tab navigation95.2%
internal/focusInternal focus manager implementation15.2%

Phase 3 (Complete)

PackageDescriptionCoverage
animationAnimation engine: tween, spring, M3 presets, orchestration (Stagger/Chain/Repeat/Reverse)92.3%
transitionWidget enter/exit animations: Fade, Slide, Scale effects, Show/Hide wrapper98.7%
core/scrollviewScrollable container: vertical/horizontal/both, wheel+keyboard+drag, PushClip/PushTransform, signal bindings96.5%
core/tabviewTabbed navigation: lazy content switching, closeable tabs, keyboard nav, Top/Bottom position, signal bindings92.1%
core/listviewVirtualized list: fixed-height items, recycling, single/multi selection, keyboard nav, M3 painter96%+
core/gridviewVirtualized 2D grid: fixed cell size, auto-fit columns, cell recycling, selection, keyboard nav92.1%
core/linechartReal-time line chart: multiple series, rolling window, grid, Y-axis labels, thread-safe PushValue98.8%
core/progressbarLinear progress bar: 0-100%, rounded corners, label, signal binding, PushClipRoundRect99.3%
core/collapsibleExpandable section: animated expand/collapse, keyboard focus, arrow indicator, Tween animation98.2%
primitivesBox (HBox/VBox direction), Text, Image, ThemeScope, RepaintBoundary94%+

Phase 4 (In Progress)

PackageDescriptionCoverage
core/progressCircular progress: determinate arc + indeterminate spinner, polyline approximation97.4%
core/popoverPopover (click) + Tooltip (hover): 12 placements, auto-flip, overlay integration97.1%
core/splitviewResizable split panels: draggable divider, min constraints, collapse, handle dots96.8%
core/treeviewHierarchical tree: expand/collapse, virtualized rendering, connector lines, keyboard nav96%+
core/datatableSortable column table: fixed header, virtualized rows, zebra striping, sort indicators96%+
core/toolbarHorizontal action bar: icon buttons, separators, spacers, custom widget items96%+
core/menuMenuBar + ContextMenu: submenus, separators, disabled items, shortcut display96%+
core/dockingIDE-style dockable panels: border layout, tabbed groups, Dock/Undock API95.3%
theme/material321 component painters (all widgets covered)97%+
theme/devtoolsJetBrains DevTools: 22 painters, Int UI gray scale, dark/light, IDE-style96%+
theme/fluentMicrosoft Fluent Design: 9 painters, accent colors, inner focus ring, light/dark96%+
theme/cupertinoApple HIG: 9 painters, iOS toggle switch, segmented control, pill buttons96%+
theme/fontFont Registry: CSS weight matching (W3C spec), Weight 100-900, Style, Family/Face97.7%
iconSVG icons (JetBrains expui), vector path icons, De Casteljau bezier, gg/svg renderer97%+
i18nInternationalization: Locale, Bundle, Translator, CLDR plural rules, RTL, LocaleSignal97.9%
dndDrag and drop: DragSource/DropTarget interfaces, Manager, 5px threshold, Escape cancel99.3%
uitestTesting utilities: MockCanvas, MockContext, event factories, widget helpers, assertions93.1%
internal/dirtyDirty region tracking: Collector, Tracker, merge algorithm, partial repaints100%

Total: ~150,000 lines of code | 55+ packages | ~6,000 tests | ~97% average coverage


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    User Application                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  theme/material3/  β”‚  theme/devtools/ β”‚  theme/fluent/      β”‚
β”‚  21 Painters       β”‚  22 Painters     β”‚  9 Painters         β”‚
β”‚  theme/cupertino/  β”‚                  β”‚                     β”‚
β”‚  9 Painters        β”‚                  β”‚                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  22 Interactive Widgets (core/)                             β”‚
β”‚  button, checkbox, radio, textfield, dropdown, slider,      β”‚
β”‚  dialog, scrollview, tabview, listview, gridview, linechart,β”‚
β”‚  progressbar, progress, collapsible, popover, splitview,    β”‚
β”‚  treeview, datatable, toolbar, menu, docking                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  cdk/        β”‚  Content[C] polymorphic pattern              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  primitives/       β”‚  animation/     β”‚  transition/         β”‚
β”‚  Box (HBox/VBox),  β”‚  Tween, Spring  β”‚  Fade, Slide, Scale  β”‚
β”‚  Text, Image,      β”‚  M3 Presets,    β”‚  Enter/Exit          β”‚
β”‚  RepaintBoundary   β”‚  Orchestration  β”‚                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  icon/  β”‚  i18n/  β”‚  dnd/   β”‚  uitest/ β”‚  theme/font/       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  app/ + FocusManager β”‚  focus/ β”‚  overlay/ β”‚  render/       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  layout/           β”‚  state/         β”‚  a11y/               β”‚
β”‚  Flex, Stack, Grid β”‚  Signals, Bind  β”‚  ARIA Roles, Tree    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  registry/         β”‚  plugin/        β”‚  theme/              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  widget/           β”‚  event/         β”‚  geometry/           β”‚
β”‚  Widget, Context   β”‚  Mouse, Key     β”‚  Point, Rect         β”‚
β”‚  Canvas, Lifecycle β”‚  Wheel, Focus   β”‚  Constraints         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  internal/render   β”‚  internal/layoutβ”‚  internal/focus      β”‚
β”‚  Canvas, Scene     β”‚  Flex, Grid     β”‚  Manager, Ring       β”‚
β”‚  internal/dirty    β”‚                 β”‚                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  gogpu/gg          β”‚  gpucontext     β”‚  coregx/signals      β”‚
β”‚  2D Graphics       β”‚  Shared Ifaces  β”‚  State Management    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dependency Principle

ui β†’ gpucontext (interfaces)       ← dependency inversion
ui β†’ gg (2D rendering)
ui β†’ coregx/signals (reactive)

gogpu β†’ gpucontext (implements)    ← concrete implementation
gg β†’ wgpu β†’ naga                   ← internal to gg

ui never imports gogpu, wgpu, or naga directly.


Examples

ExampleDescription
examples/helloWidget demo: checkbox, radio, ListView (1000 items), M3 theme, event-driven GPU rendering
examples/signalsReactive signals: TextSignal, ContentSignal, CheckedSignal, SelectedSignal, DisabledSignal
examples/taskmanagerFull task manager: charts, tables, animations, real-time data
examples/galleryWidget gallery: all 22 widgets, 4 design systems (M3/DevTools/Fluent/Cupertino), theme switching
examples/ideGoLand-inspired IDE layout: DevTools theme, toolbar, tree, tabs, terminal, SVG icons

Run any example:

cd examples/gallery
go run .

API Examples

Primitives

// Box β€” universal container
primitives.Box(children...).
    Padding(16).
    PaddingXY(24, 8).
    Background(theme.Surface).
    Rounded(8).
    BorderStyle(1, theme.Outline).
    ShadowLevel(2).
    Gap(8)

// Text β€” static
primitives.Text("Hello World").
    FontSize(24).
    Bold().
    Color(theme.OnSurface).
    Align(primitives.TextAlignCenter).
    MaxLines(2).
    Ellipsis()

// Text β€” reactive (auto-updates when signal changes)
primitives.TextFn(func() string {
    return fmt.Sprintf("Count: %d", count.Get())
}).FontSize(18)

// Text β€” signal binding (auto-updates when signal changes)
title := state.NewSignal("Hello World")
primitives.NewText("").ContentSignal(title).FontSize(24)

// Image
primitives.Image(mySource).
    Size(48, 48).
    Cover().
    Rounded(24).
    Alt("User avatar")

Slider

// Basic slider
s := slider.New(
    slider.Min(0),
    slider.Max(100),
    slider.Value(50),
    slider.OnChange(func(v float32) { fmt.Println("Value:", v) }),
)

// Discrete slider with step snapping and marks
s := slider.New(
    slider.Min(0), slider.Max(100), slider.Step(10),
    slider.Marks([]slider.Mark{{Value: 0}, {Value: 50}, {Value: 100}}),
    slider.PainterOpt(material3.SliderPainter{Theme: m3}),
)

// Two-way signal binding
volume := state.NewSignal[float32](75)
s := slider.New(
    slider.Min(0), slider.Max(100),
    slider.ValueSignal(volume),  // reads AND writes back on drag
)

Dialog

// Simple alert dialog
d := dialog.Alert("Error", "File not found.", func() { log.Println("dismissed") })
d.Show(ctx)

// Confirmation dialog
d := dialog.Confirm("Delete?", "This cannot be undone.",
    func() { log.Println("canceled") },
    func() { deleteItem() },
)
d.Show(ctx)

// Custom dialog with M3 painter
d := dialog.New(
    dialog.Title("Settings"),
    dialog.Content(settingsWidget),
    dialog.Actions(
        dialog.Action{Label: "Cancel", Variant: dialog.VariantTextOnly},
        dialog.Action{Label: "Save", Variant: dialog.VariantFilled, Default: true,
            OnClick: func() { saveSettings() }},
    ),
    dialog.PainterOpt(material3.DialogPainter{Theme: m3}),
)
d.Show(ctx)

Animation

// Tween animation with M3 easing
ctrl := animation.NewController()
opacity := state.NewSignal[float32](0)
animation.To(opacity, 1.0).
    Duration(animation.DurationMedium2).
    Ease(animation.M3Standard).
    Start(ctrl)

// Spring physics (critically damped)
position := state.NewSignal[float32](0)
animation.SpringTo(position, 200).
    Stiffness(animation.StiffnessMedium).
    DampingRatio(animation.DampingNoBouncy).
    Start(ctrl)

// Color tween (Flutter pattern: float32 engine + Tween[T])
progress := state.NewSignal[float32](0)
animation.To(progress, 1.0).Duration(300*time.Millisecond).Start(ctrl)
colorTween := animation.NewColorTween(startColor, endColor)
// in Draw: canvas.DrawRect(bounds, colorTween.At(progress.Get()))

// Parallel composition
animation.Parallel(
    animation.To(opacity, 1.0).Duration(200*time.Millisecond),
    animation.To(translateY, 0).Duration(300*time.Millisecond),
).Start(ctrl)

ScrollView

// Basic vertical scrollview
sv := scrollview.New(longContentWidget,
    scrollview.DirectionOpt(scrollview.Vertical),
    scrollview.ScrollbarOpt(scrollview.ScrollbarAuto),
    scrollview.OnScroll(func(x, y float32) { fmt.Printf("scroll: %.0f\n", y) }),
)

// 2D scrollview with signal binding
scrollY := state.NewSignal[float32](0)
sv := scrollview.New(largeCanvas,
    scrollview.DirectionOpt(scrollview.Both),
    scrollview.ScrollYSignal(scrollY), // two-way binding
    scrollview.PainterOpt(material3.ScrollbarPainter{Theme: m3}),
)

TabView

// Basic tab view
tv := tabview.New([]tabview.Tab{
    {Label: "Profile", Content: profileWidget},
    {Label: "Settings", Content: settingsWidget},
    {Label: "About", Content: aboutWidget},
}, tabview.OnSelect(func(idx int) { fmt.Println("Tab:", idx) }))

// Closeable tabs with M3 painter and signal binding
selected := state.NewSignal[int](0)
tv := tabview.New(tabs,
    tabview.Closeable(true),
    tabview.SelectedSignalOpt(selected),
    tabview.PainterOpt(material3.TabViewPainter{Theme: m3}),
    tabview.OnClose(func(idx int) { removeDynamicTab(idx) }),
)

Reactive State

// Create a signal
name := state.NewSignal("World")

// Computed value (auto-updates)
greeting := state.NewComputed(func() string {
    return "Hello, " + name.Get() + "!"
})

// Bind signal to widget invalidation
binding := state.Bind(name, ctx)
defer binding.Unbind()

// Batch multiple changes (single re-render)
scheduler.Batch(func() {
    firstName.Set("Alice")
    lastName.Set("Smith")
    age.Set(30)
})

Widget Signal Bindings

// Bind signals directly to widget properties
label := state.NewSignal("Submit")
disabled := state.NewSignal(false)

btn := button.New(
    button.TextSignal(label),
    button.DisabledSignal(disabled),
    button.OnClick(func() {
        label.Set("Processing...")
        disabled.Set(true)
    }),
)

// Two-way binding: checkbox state synced with signal
agreed := state.NewSignal(false)
cb := checkbox.New(
    checkbox.CheckedSignal(agreed),
    checkbox.LabelOpt("I agree to terms"),
)

Accessibility

// Every widget implements a11y.Accessible
func (b *MyButton) AccessibilityRole() a11y.Role   { return a11y.RoleButton }
func (b *MyButton) AccessibilityLabel() string      { return b.text }
func (b *MyButton) AccessibilityActions() []a11y.Action {
    return []a11y.Action{a11y.ActionClick}
}

// Accessibility tree with stable node IDs
root := a11y.NewNode(a11y.RoleWindow, "My Application")
tree := a11y.NewMemoryTree(root)
button := a11y.NewNode(a11y.RoleButton, "Save")  // stable uint64 ID
tree.Insert(root, button)

Window Integration

// ui connects to windowing via interfaces (not concrete types)
uiApp := app.New(
    app.WithWindowProvider(gogpuApp),    // gpucontext.WindowProvider
    app.WithPlatformProvider(gogpuApp),  // gpucontext.PlatformProvider
    app.WithTheme(myTheme),
)

uiApp.SetRoot(rootWidget)

// Headless mode for testing (no window needed)
testApp := app.New()  // works without any providers
testApp.SetRoot(rootWidget)
testApp.Window().Frame()  // processes layout + draw

Implementation Progress

Phase 0: Foundation βœ…

  • Geometry types (Point, Size, Rect, Constraints, Insets)
  • Event system (Mouse, Keyboard, Wheel, Focus, Modifiers)
  • Widget interface, WidgetBase, Context, Canvas
  • Layout engines (Flexbox, Stack, Grid)
  • Canvas implementation (gogpu/gg)

Phase 1: MVP βœ…

  • Accessibility foundation (35+ ARIA roles, Accessible interface, Tree)
  • Reactive signals integration (coregx/signals, Binding, Scheduler)
  • Basic primitives (Box, Text, Image with fluent API)
  • Window integration (app package via gpucontext interfaces)

Phase 1.5: Extensibility βœ…

  • Widget Registry (third-party registration)
  • Public Layout API (custom algorithms)
  • Theme System + Extensions + Registry
  • Plugin System (bundling, dependency resolution)

Phase 2: Beta βœ…

  • Button widget (4 variants, 3 sizes, keyboard activation)
  • Checkbox widget (checked/unchecked/indeterminate, pluggable Painter)
  • Radio group widget (vertical/horizontal, arrow key navigation)
  • TextField widget (cursor, selection, clipboard, validation)
  • Dropdown/Select widget (overlay menu, keyboard nav, scroll)
  • Overlay infrastructure (stack, container, position)
  • Material Design 3 theme (HCT color science, 21 painters)
  • Keyboard navigation (focus management, Tab/Shift+Tab, shortcuts)
  • ThemeScope (theme override for widget subtrees)
  • Event-driven rendering (0% CPU when idle)
  • Reactive signal bindings for all widgets (TextSignal, CheckedSignal, SelectedSignal, DisabledSignal, ContentSignal)

Phase 3: Release Candidate βœ…

  • Retained-mode rendering: dirty tracking, DrawTree, DrawStats (SP1)
  • RepaintBoundary: per-widget pixel caching (SP2)
  • scene.Scene integration: tile-parallel rendering via SceneCanvas (SP3)
  • Slider widget (continuous/discrete, horizontal/vertical, M3 painter)
  • Dialog/Modal widget (backdrop, actions, focus trapping, M3 painter)
  • Animation engine (Tween, Spring, CubicBezier, M3 motion tokens)
  • Animation presets (M3 motion tokens) + orchestration (Stagger, Chain, Repeat)
  • Transitions: enter/exit animations (Fade, Slide, Scale)
  • ScrollView widget (vertical/horizontal/both, wheel+keyboard+drag)
  • TabView widget (lazy content, closeable tabs, keyboard nav)
  • ListView widget (virtualized list, recycling, single/multi selection, M3 painter)
  • GridView widget (virtualized 2D grid, auto-fit columns, cell recycling)
  • LineChart widget (real-time, multiple series, rolling window)
  • ProgressBar widget (linear, rounded corners, signal binding)
  • Collapsible section widget (animated expand/collapse)
  • Box HBox/VBox direction support
  • Dirty region tracking (internal/dirty)
  • Performance benchmarks (36 across 5 packages)

Phase 4: Production (v1.0) β€” In Progress

  • Circular progress indicator (determinate arc + indeterminate spinner)
  • SplitView (resizable split panels, draggable divider)
  • Popover/Tooltip (12 placements, auto-flip, overlay)
  • TreeView (hierarchical, expand/collapse, virtualized)
  • DataTable (sortable columns, fixed header, virtualized rows)
  • Toolbar (icon buttons, separators, spacers)
  • Menu system (MenuBar + ContextMenu, submenus, shortcuts)
  • IDE-style docking system (border layout, tabbed groups)
  • Drag & drop foundation (DragSource, DropTarget, Manager)
  • Fluent Design theme (9 painters, accent colors)
  • Cupertino theme (9 painters, iOS-style)
  • i18n (CLDR plural rules, RTL detection, LocaleSignal)
  • Icon system (vector paths, 10 Material icons, De Casteljau)
  • Font registry (CSS weight matching, W3C spec)
  • Testing utilities (MockCanvas, MockContext, assertions)
  • Dirty region tracking (merge algorithm, partial repaints)
  • Performance benchmarks (36 across 5 packages)
  • Hover tracking (W3C PointerEventSource, HoverTracker, cursor management)
  • ScreenBounds coordinate system (overlay positioning, hit-testing)
  • Event coordinate transforms (ScrollView content-space dispatch)
  • Inter font full Unicode (Cyrillic, Greek, Vietnamese)
  • MeasureText on Canvas (layout calculations without drawing)
  • FocusManager integration in Window (Tab/Shift+Tab navigation)
  • OnTextInput handler (platform character input API)
  • Task Manager example (charts, tables, animations)
  • Widget Gallery example (all widgets, 4 design systems, theme switching)
  • Platform accessibility adapters (UIA, AT-SPI2, NSAccessibility)
  • Performance optimization pass

Requirements

DependencyPurposeStatus
Go 1.25+Language runtimeRequired
CGO_ENABLED=0Pure Go (no C compiler needed)Default
gogpu/gogpuWindowing, input, GPU surfaceFor examples
gogpu/gg2D graphics renderingIntegrated
gogpu/gpucontextShared interfacesIntegrated
coregx/signalsReactive state managementIntegrated

Note: The entire ecosystem is pure Go. Do not set CGO_ENABLED=1 β€” this will cause build errors from the goffi package which requires CGO to be disabled.


Installation

# UI toolkit (library)
go get github.com/gogpu/ui@latest

# For runnable applications you also need gogpu (windowing) and gg (rendering):
go get github.com/gogpu/gogpu@latest
go get github.com/gogpu/gg@latest

Related Projects

ProjectDescription
gogpu/gogpuGraphics framework β€” GPU abstraction, windowing, input
gogpu/gg2D graphics β€” Canvas API, GPU text
gogpu/wgpuPure Go WebGPU β€” Vulkan, Metal, GLES, Software
gogpu/nagaShader compiler β€” WGSL to SPIR-V, MSL, GLSL

Total ecosystem: 300K+ lines of Pure Go β€” no CGO, no Rust, no C.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines.

Ways to contribute:

  • Test the packages, report bugs
  • API feedback and suggestions
  • Documentation improvements
  • Spread the word (Reddit, Hacker News, Dev.to)
  • Code contributions (see open issues)

License

MIT License β€” see LICENSE for details.


gogpu/ui β€” Enterprise-grade GUI for Go
Part of the GoGPU ecosystem