A Go port of gpui-component — a shadcn/ui-inspired UI component library built on top of the gogpu / gogpu/gg GPU rendering ecosystem.
gogpui brings the look and feel of gpui-component (a 60+ component Rust UI library) to Go.
It runs on a GPU-accelerated, immediate-mode rendering pipeline — every frame is drawn from scratch on the GPU, with no DOM or CSS involved.
Key properties:
- shadcn/ui-faithful design — colors, spacing, and interaction states match the Rust original
- Immediate-mode API — no retained widget trees; components are declared per frame
- Fluent builder API — chainable methods for zero-boilerplate widget setup
- Dark / Light mode — theme switching at runtime
- Fully tested — golden-image diff tests + synthetic-input unit tests per component
go get github.com/sofiagros/gogpuiRequires Go 1.26+ and a WebGPU-capable GPU driver (via github.com/gogpu/gogpu).
package main
import (
gogpui "github.com/sofiagros/gogpui"
"github.com/sofiagros/gogpui/components/button"
"github.com/sofiagros/gogpui/core/context"
"github.com/sofiagros/gogpui/core/layout"
)
func main() {
app := gogpui.New(gogpui.Options{
Title: "My App",
Width: 800,
Height: 600,
})
var clicked int
app.Run(func(uictx *context.UIContext) {
btn := button.New("my-button").
Label("Click Me").
Primary()
layout.NewFlex().
Direction(layout.Column).
Gap(10).
Add(btn).
Render(uictx, 50, 50)
})
}| Component | Status | Variants / Notes |
|---|---|---|
Button |
✅ Done | Primary · Danger · Link · Ghost · Outline |
Checkbox |
✅ Done | Default · Checked · Disabled |
Switch |
✅ Done | Default · Checked · Disabled |
Radio |
✅ Done | Default · Checked · Disabled |
Slider |
✅ Done | Continuous · Disabled |
Label |
✅ Done | Normal · Secondary · Highlights · Masked |
Badge |
✅ Done | Count · Max cap · Dot · Custom color |
See
PORTING_LEDGER.mdfor the full progress table and per-component API mapping to the Rust source.
button.New("id").Label("Save").Primary()
button.New("id").Label("Delete").Danger()
button.New("id").Label("Cancel").Link()checkbox.New("id").Label("Remember me").Checked(val).OnChange(func(v bool) { val = v })
switch_comp.New("id").Label("Notifications").Checked(val).OnChange(func(v bool) { val = v })
radio.New("id").Label("Option A").Checked(val).OnChange(func(v bool) { val = v })slider.New("id").Value(sliderVal).OnChange(func(v float64) { sliderVal = v })
slider.New("id").Value(0.5).Disabled(true)label.New("Normal text")
label.New("Title").Secondary("subtitle")
label.New("Search results").Highlights("earch", false)
label.New("secret").Masked(true)badge.New().Count(5).Add(label.New("Messages"))
badge.New().Count(120).Max(99).Add(label.New("Notifications"))
badge.New().Dot().Add(label.New("Updates"))
badge.New().Count(3).Color(th.Colors.Info).Add(label.New("Info"))// Flex — 行/列方向に並べる
layout.NewFlex().
Direction(layout.Column). // または layout.Row
Gap(10).
Add(btn1, btn2, btn3).
Render(uictx, x, y)
// Grid — 固定列数グリッド
layout.NewGrid().Cols(3).Gap(8).
Add(a, b, c, d, e, f).
Render(uictx, x, y)
// Spacer — 残りスペースを埋める (flex-grow 相当)
layout.NewFlex().Direction(layout.Row).Add(
label.New("Left"),
layout.NewSpacerFlex(), // ← ここが伸びる
label.New("Right"),
)
// Padding — 子ウィジェットに余白を追加
layout.NewPadding(btn).Horizontal(12).Vertical(4)gogpui/
├── gogpui.go # App ラッパー — gogpu/gg を隠蔽するトップレベル API
├── components/ # UI コンポーネント
│ ├── button/
│ ├── checkbox/
│ ├── switch/
│ ├── radio/
│ ├── slider/
│ ├── label/
│ └── badge/
├── core/
│ ├── context/ # UIContext — フレームごとの入力・テーマキャリア
│ ├── layout/ # Flex / Grid / Spacer / Padding レイアウトエンジン
│ └── theme/ # ライト / ダークテーマトークン
├── assets/
│ └── fonts/ # Inter フォント (Vector / MSDF レンダリング)
├── cmd/
│ └── showcase/ # インタラクティブコンポーネントギャラリー
├── testing/ # ゴールデンイメージ差分テスト用ヘルパー
└── docs/
├── porting-pattern.md # GPUI → gogpu/gg コンセプトマッピング
└── PORTING_LEDGER.md # コンポーネント単位の進捗・API対応表
gogpui は gogpu/gg の GPU 即時モードレンダリング パイプライン上で動作します。 リテインドウィジェットツリー・DOM・CSS レイアウトエンジンは存在せず、毎フレームフルシーンを GPU ドローコールとして再発行します。
ユーザーコードは gogpu や ggcanvas を直接インポートする必要はありません。
gogpui.New + app.Run がフォント・入力・キャンバスの初期化を一括して管理します。
オーバーレイウィジェット(ドロップダウン、ツールチップ、ポップオーバー)を実装する際の注意: アンカー座標は毎フレーム再計算する必要があります。 オーバーレイが開いたフレームの座標をキャッシュすると、スクロール時に座標がずれます。
git clone https://github.com/sofiagros/gogpui
cd gogpui
go run ./cmd/showcaseContributions are welcome. Before starting work on a new component, please read:
docs/porting-pattern.md— established GPUI → gogpu/gg concept mappingsPORTING_LEDGER.md— current component status and API correspondence table
Source of truth:
- Rust source:
crates/ui/src - Live gallery (WASM): longbridge.github.io/gpui-component
When in doubt about a component's visual or behavioral spec, open the live gallery and verify directly — do not guess.
- Public API matches the Rust original 1:1 (recorded in
PORTING_LEDGER.md) - Golden-image diff test passes (diff score noted)
- Unit tests cover hover / focus / click / disabled / open-close state transitions using synthetic input events
-
go test ./...is green
