Enterprise-Grade GUI Toolkit for Go
Modern widgets, reactive state, GPU-accelerated rendering — zero CGO
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
| Feature | gogpu/ui | Fyne | Gio |
|---|---|---|---|
| CGO-free | Yes | No | Yes |
| WebGPU rendering | Yes (Vulkan/DX12/Metal/GLES/Software) | OpenGL | Direct GPU |
| Reactive state | Signals (push-pull, zero glitch) | Binding | Events |
| Layout engine | Flexbox + Grid + per-widget cache | Custom | Flex |
| Accessibility | Day 1 (35+ ARIA roles) | Limited | Limited |
| Design systems | 4 (M3, DevTools, Fluent, Cupertino) | 1 | 1 |
| Widgets | 26 interactive + primitives | ~20 | ~15 |
| Plugin system | Yes (deps, assets, fonts) | No | No |
| Android | In review (wgpu#268) | Yes | Yes |
Screenshot
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 using desktop.Run (recommended):
package main import ( "log" _ "github.com/gogpu/gg/gpu" "github.com/gogpu/gogpu" "github.com/gogpu/ui/app" "github.com/gogpu/ui/desktop" "github.com/gogpu/ui/primitives" "github.com/gogpu/ui/widget" ) func main() { gogpuApp := gogpu.NewApp(gogpu.DefaultConfig(). WithTitle("My App"). WithSize(800, 600)) 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)), ) if err := desktop.Run(gogpuApp, uiApp); err != nil { log.Fatal(err) } }
Packages
Core (Phase 0)
| Package | Description | Coverage |
|---|---|---|
geometry |
Point, Size, Rect, Constraints, Insets | 98.8% |
event |
MouseEvent, KeyEvent, WheelEvent, FocusEvent, Modifiers | 100% |
widget |
Widget, WidgetBase, Context, Canvas, Lifecycle (mount/unmount), SchedulerRef | 100% |
internal/render |
Canvas, SceneCanvas, IconCache (2-level LRU), DPI-aware SVG | 96.5% |
internal/layout |
Flex, Stack, Grid layout engines | 89.9% |
MVP (Phase 1)
| Package | Description | Coverage |
|---|---|---|
a11y |
Accessibility: 35+ ARIA roles, Accessible interface, Tree, Announcer | 99.1% |
state |
Reactive signals, Binding, Scheduler with push-based invalidation | 100% |
primitives |
Box, Text, Image widgets with fluent builder API | 94.4% |
app |
Window integration via gpucontext interfaces (dependency inversion) | 98.6% |
Extensibility (Phase 1.5)
| Package | Description | Coverage |
|---|---|---|
layout |
Public layout API with custom algorithms | 89.5% |
registry |
Widget factory registration for third-party widgets | 100% |
theme |
Theme system with Extensions and Registry | 100% |
plugin |
Plugin bundling with dependency resolution | 99.4% |
Interactive Widgets (Phase 2 — Complete)
| Package | Description | Coverage |
|---|---|---|
cdk |
Component Development Kit — Content[C] polymorphic pattern | 100% |
core/button |
Generic button with pluggable Painter, 4 variants, 3 sizes, signal bindings | 96%+ |
core/checkbox |
Toggleable checkbox with checked/unchecked/indeterminate states, signal bindings | 96%+ |
core/radio |
Mutually exclusive radio group with vertical/horizontal layout, signal bindings | 96%+ |
core/textfield |
Text input with cursor, selection, clipboard, validation, signal bindings | 96%+ |
core/slider |
Slider: continuous/discrete, horizontal/vertical, drag+keyboard, signal bindings | 94.6% |
core/dialog |
Modal dialog: backdrop overlay, action buttons, focus trapping, Alert/Confirm | 96.9% |
core/dropdown |
Dropdown/select with overlay menu, keyboard navigation, signal bindings | 96%+ |
overlay |
Overlay/popup stack, container, position helper | 95%+ |
primitives |
Box, Text, Image, RepaintBoundary (GPU texture caching via Layer Tree compositor) | 94.4% |
theme/material3 |
Material Design 3 — theme (HCT color science) + 24 component painters | 97%+ |
focus |
Keyboard focus management with Tab/Shift+Tab navigation | 95.2% |
internal/focus |
Internal focus manager implementation | 15.2% |
Phase 3 (Complete)
| Package | Description | Coverage |
|---|---|---|
animation |
Animation engine: tween, spring, M3 presets, orchestration (Stagger/Chain/Repeat/Reverse) | 92.3% |
transition |
Widget enter/exit animations: Fade, Slide, Scale effects, Show/Hide wrapper | 98.7% |
core/scrollview |
Scrollable container: vertical/horizontal/both, wheel+keyboard+drag, PushClip/PushTransform, signal bindings | 96.5% |
core/tabview |
Tabbed navigation: lazy content switching, closeable tabs, keyboard nav, Top/Bottom position, signal bindings | 92.1% |
core/listview |
Virtualized list: fixed-height items, recycling, single/multi selection, keyboard nav, M3 painter | 96%+ |
core/gridview |
Virtualized 2D grid: fixed cell size, auto-fit columns, cell recycling, selection, keyboard nav | 92.1% |
core/linechart |
Real-time line chart: multiple series, rolling window, grid, Y-axis labels, thread-safe PushValue | 98.8% |
core/progressbar |
Linear progress bar: 0-100%, rounded corners, label, signal binding, PushClipRoundRect | 99.3% |
core/collapsible |
Expandable section: animated expand/collapse, keyboard focus, arrow indicator, Tween animation | 98.2% |
primitives |
Box (HBox/VBox direction), Text, Image, ThemeScope, RepaintBoundary | 94%+ |
Phase 4 (In Progress)
| Package | Description | Coverage |
|---|---|---|
core/progress |
Circular progress: determinate arc + indeterminate spinner, polyline approximation | 97.4% |
core/popover |
Popover (click) + Tooltip (hover): 12 placements, auto-flip, overlay integration | 97.1% |
core/splitview |
Resizable split panels: draggable divider, min constraints, collapse, handle dots | 96.8% |
core/treeview |
Hierarchical tree: expand/collapse, virtualized rendering, connector lines, keyboard nav | 96%+ |
core/datatable |
Sortable column table: fixed header, virtualized rows, zebra striping, sort indicators | 96%+ |
core/toolbar |
Horizontal action bar: icon buttons, separators, spacers, custom widget items | 96%+ |
core/menu |
MenuBar + ContextMenu: submenus, separators, disabled items, shortcut display | 96%+ |
core/docking |
IDE-style dockable panels: border layout, tabbed groups, Dock/Undock API | 95.3% |
core/badge |
Notification badge: count mode (pill, "99+" overflow), dot mode, signal bindings with dedup | 99.3% |
core/chip |
Action/filter chip (M3 spec): toggleable selection, two-way signal write-back, state layers | 99.0% |
theme/material3 |
24 component painters (all widgets covered) | 97%+ |
theme/devtools |
JetBrains DevTools: 24 painters, Int UI gray scale, dark/light, IDE-style | 96%+ |
theme/fluent |
Microsoft Fluent Design: 11 painters, accent colors, inner focus ring, light/dark | 96%+ |
theme/cupertino |
Apple HIG: 11 painters, iOS toggle switch, segmented control, pill buttons | 96%+ |
theme/font |
Font Registry: CSS weight matching (W3C spec), Weight 100-900, Style, Family/Face | 97.7% |
icon |
SVG icons (JetBrains expui), 2-level cache, DPI-aware rasterization, gg/svg renderer | 97%+ |
i18n |
Internationalization: Locale, Bundle, Translator, CLDR plural rules, RTL, LocaleSignal | 97.9% |
dnd |
Drag and drop: DragSource/DropTarget interfaces, Manager, 5px threshold, Escape cancel | 99.3% |
offscreen |
Headless widget rendering: CPU-only *image.RGBA output, no GPU/window/app required |
100% |
uitest |
Testing utilities: MockCanvas, MockContext, event factories, widget helpers, assertions | 93.1% |
internal/dirty |
Dirty region tracking: Collector, Tracker, merge algorithm, partial repaints | 100% |
| core/stripe | Vertical sidebar strip: tool window buttons, top/bottom items, icon buttons | 96%+ |
| core/titlebar | Window title bar: CSD, drag, minimize/maximize/close, WindowChrome interface | 96%+ |
| compositor | Layer Tree compositor: OffsetLayer, PictureLayer, ClipRectLayer, OpacityLayer — production render pipeline | 95%+ |
| desktop | Production render loop: Layer Tree → GPU textures → damage-aware blit | — |
Total: ~207,000+ lines of code | 56+ packages | ~7,500+ tests | 97%+ average coverage
Backend Selection
gogpu/ui renders through any GPU backend via the gogpu ecosystem — no code changes needed:
GOGPU_GRAPHICS_API=vulkan go run ./examples/hello/ # Vulkan (default on Linux) GOGPU_GRAPHICS_API=dx12 go run ./examples/hello/ # DirectX 12 (Windows) GOGPU_GRAPHICS_API=metal go run ./examples/hello/ # Metal (macOS) GOGPU_GRAPHICS_API=gles go run ./examples/hello/ # OpenGL ES GOGPU_GRAPHICS_API=software go run ./examples/hello/ # CPU software renderer
The software backend runs on any machine without GPU drivers. It uses the same unified render pipeline (Layer Tree compositor, offscreen boundary textures, damage-aware blit) as GPU backends. Performance is significantly slower than GPU — optimization via naga Go+SIMD backend (NAGA-FEAT-004) is planned.
Android support is in review (wgpu#268) — Vulkan on arm64, contributed by @besmpl for Hearth game engine.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ User Application │
├─────────────────────────────────────────────────────────────┤
│ theme/material3/ │ theme/devtools/ │ theme/fluent/ │
│ 24 Painters │ 24 Painters │ 11 Painters │
│ theme/cupertino/ │ │ │
│ 11 Painters │ 70 painters total across 4 systems │
├─────────────────────────────────────────────────────────────┤
│ 26 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, badge, chip, │
│ stripe, titlebar │
├──────────────┬──────────────────────────────────────────────┤
│ 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/ │
├─────────────────────────────────────────────────────────────┤
│ desktop/ (Layer Tree Compositor + Damage-Aware Blit) │
│ compositor/ (Production: OffsetLayer, PictureLayer, Opacity)│
│ offscreen/ (headless widget → *image.RGBA) │
├─────────────────────────────────────────────────────────────┤
│ 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 │
│ IconCache (LRU) │ internal/dirty │ Tracker, Collector │
├─────────────────────────────────────────────────────────────┤
│ 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.
Render Pipeline
Enterprise-grade retained-mode rendering (ADR-007) with unified draw queue (ADR-051/052):
- O(1) frame skip — flat dirty boundary set, no tree walks when idle (0% GPU)
- Layer Tree composition — OffsetLayer, PictureLayer, OpacityLayer, ClipRectLayer
- Per-boundary GPU textures — dirty boundaries re-render to MSAA offscreen texture, clean reuse cached
- Damage-aware blit — LoadOpLoad + multi-rect scissor, only dirty pixels touch the GPU
- Persistent tree — layer objects reused across frames (97.9% fewer allocations)
- Unified draw queue — backend-agnostic command dispatch (shapes, text, GPU textures through single pipeline). GPU backends batch into render passes; software dispatches through CPU rasterizer.
Validated by enterprise research: Flutter, Chrome, Qt6, Android, Skia patterns. Works on all backends: Vulkan, DX12, Metal, GLES, Software, Browser (WASM).
Examples
| Example | Description |
|---|---|
examples/hello |
Widget demo: checkbox, radio, ListView (1000 items), M3 theme, event-driven GPU rendering |
examples/signals |
Reactive signals: TextSignal, ContentSignal, CheckedSignal, SelectedSignal, DisabledSignal |
examples/taskmanager |
Full task manager: charts, tables, animations, real-time data |
examples/gallery |
Widget gallery: all 26 widgets, 4 design systems (M3/DevTools/Fluent/Cupertino), theme switching |
examples/ide |
GoLand-inspired IDE layout: DevTools theme, toolbar, tree, tabs, terminal, SVG icons |
examples/modular-compositor |
Multi-module offscreen rendering: clock + notification compositor (#75) |
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)
Offscreen Rendering
// Render widgets to image without GPU, window, or app r := offscreen.NewRenderer(400, 120) r.Render(primitives.Text("Hello, World!").FontSize(24)) img := r.Image() // *image.RGBA — ready for png.Encode, testing, compositing // HiDPI with dark theme and white background dark := material3.NewDark(widget.Hex(0x00BFA5)) r := offscreen.NewRenderer(800, 240, offscreen.WithTheme(dark), offscreen.WithScale(2.0), offscreen.WithBackground(widget.ColorWhite), ) r.Render(myWidgetTree)
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, 24 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 (11 painters, accent colors)
- Cupertino theme (11 painters, iOS-style)
- Badge widget (notification count/dot, signal bindings)
- Chip widget (action/filter, toggleable, two-way signal)
- Stripe widget (sidebar tool buttons)
- TitleBar widget (CSD window title bar)
- 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)
- Incremental rendering pipeline (ADR-004): frame skip, persistent pixmap, dirty regions
- Auto RepaintBoundary in ListView (per-item pixel caching)
- DrawStats observability (CachedWidgets, DirtyRegionCount)
- Tracker.Intersects() fast path in RepaintBoundary
- Centralized ImageCache with LRU eviction (64MB, thread-safe)
- Offscreen renderer (headless widget → *image.RGBA, no GPU/window)
- Layout cache per-widget (ADR-032, LayoutChild, O(subtree))
- Animation before layout (GAP-3, Flutter BeginFrame pattern)
- Unified draw queue (ADR-051/052, backend-agnostic pipeline)
- Platform accessibility adapters (UIA, AT-SPI2, NSAccessibility)
- Software backend performance optimization (naga Go+SIMD, SPIR-V SIMD)
- Android support (wgpu#268, Vulkan arm64)
Requirements
| Dependency | Purpose | Status |
|---|---|---|
| Go 1.25+ | Language runtime | Required |
| CGO_ENABLED=0 | Pure Go (no C compiler needed) | Default |
| gogpu/gogpu | Windowing, input, GPU surface | For examples |
| gogpu/gg | 2D graphics rendering | Integrated |
| gogpu/gpucontext | Shared interfaces | Integrated |
| coregx/signals | Reactive state management | Integrated |
Note: The entire ecosystem is pure Go. Do not set
CGO_ENABLED=1— this will cause build errors from thegoffipackage 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
| Project | Description |
|---|---|
| gogpu/gogpu | Graphics framework — GPU abstraction, windowing, input |
| gogpu/gg | 2D graphics — Canvas API, GPU text |
| gogpu/wgpu | Pure Go WebGPU — Vulkan, Metal, DX12, GLES, Software, Browser |
| gogpu/naga | Shader compiler — WGSL to SPIR-V, MSL, GLSL, HLSL, DXIL |
| gogpu/g3d | Pure Go 3D rendering — scene graph, PBR, forward renderer |
| gogpu/compose | Multi-process composition — Unix socket, LZ4, hot-plug |
| gogpu/audio | Pure Go audio engine — WASAPI, WAV decoder, Mixer |
Total ecosystem: 1.14M+ lines of Pure Go — zero CGO, Rust optional via -tags rust (ADR-038). Android/arm64 in review.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
Ways to contribute:
- Test the packages, report bugs
- API feedback and suggestions
- Documentation improvements
- Software backend profiling and optimization
- Spread the word (Hacker News, Dev.to, GitHub Discussions)
- Code contributions (see open issues)
License
MIT License — see LICENSE for details.
Star History
gogpu/ui — Enterprise-grade GUI for Go
Part of the GoGPU ecosystem

