Introduction
gpui-go lets a Go program open windows and draw interfaces with GPUI, the Rust UI framework behind the Zed editor. Your application logic stays in ordinary Go, with goroutines and context.Context.
How it works
You describe a window's contents as a tree of elements. Go sends that tree to Rust as a versioned protobuf message, and GPUI lays out and paints it. Clicks and keystrokes come back as events that your Go handlers process.
The tree on the left produces the window on the right. Each element has a stable ID that ties it to its native state.
Every update takes this path. Your code stays in ordinary Go, and GPUI runs on the process main thread.
Sable is the library that connects the Go and Rust runtimes. It lets a goroutine await an asynchronous Rust operation much as it would wait on a channel: the goroutine parks until Rust delivers the result, no OS thread stays blocked on the call, and canceling the context.Context reaches the pending operation. gpui-go uses it as a request and response transport for protobuf bytes, so commands and event pulls are ordinary awaited calls, and no Go pointers or callbacks cross into rendering.
Sable can also merge the Go and Rust schedulers around a single event loop, but gpui-go does not use that mode. It selects Sable's portable backend (the sable_portable build tag), which relies only on supported Go APIs, and GPUI keeps its own platform event loop and executors. You don't call Sable directly: host.Run starts and stops it for you.
GPUI renders the latest snapshot entirely in Rust and never waits for Go during a frame, so a busy goroutine does not stall painting. Interactive state that has to feel native, such as focus, text selection, IME composition and scroll position, is owned by Rust and survives each snapshot you send.
Go decides what the view contains. Rust owns everything that has to respond within a frame, and that state survives each new snapshot.
See Concepts for how snapshots, element IDs and events work in practice.
Packages
Everything lives in the module github.com/moriyoshi/gpui-go.
| Package | Use it for |
|---|---|
host | Starting the native runtime with host.Run |
client | Windows, events, resources, models and platform commands |
scene | Building element trees and styles |
reactive, ui | Signals, memos, effects and persistent component nodes |
ui/gox | Writing views as GoX templates |
uitest, uitest/gpui | Page, Locator and expect-style end-to-end tests |
editor | The optional, GPL-licensed Zed editor component |
The root package gpui keeps compatibility aliases for older code. New code should import client and scene directly.
Status
Headless protocol tests exercise the real Sable transport. Native builds and desktop smoke tests are verified on macOS/arm64. On Linux, the end-to-end suites pass without a display. Linux with a real display and Windows have partial build work for prebuilt modules, but their native runtime behavior is not validated.
Not yet validated on any platform: real OS IME composition, drag-and-drop gestures, screen-reader output and pixel-level rendering.
Outside the current API: arbitrary Rust Render implementations, custom shaders, variable-height or paged lists, styled text runs and incremental snapshot patches. Generic text inputs are single-line, with no undo/redo.
License
gpui-go is licensed under the Apache License, Version 2.0, including the Go packages, protobuf schemas, examples and the generic Rust backend. The optional Rust Zed editor component and host are GPL-3.0-or-later. Third-party code and assets keep their own licenses.