[RFC] gogpu/ui — Enterprise-Grade GUI Toolkit for Go #18
Replies: 15 comments 9 replies
-
Angular 20/21 Patterns Proposals (December 25, 2025)After researching Angular 20/21 architecture, we propose additional patterns that could enhance gogpu/ui. These are proposals for community discussion, not final decisions. Proposed Patterns
1. linkedSignalDerived value that can be overridden, then reset: // Form field linked to source, but editable
name := signals.NewLinked(func() string { return user.Get().Name })
name.Set("Override") // User edits
name.Reset() // Back to derived value
name.IsDirty() // Check if modified2. Signal FormsForm-level abstraction with validation: form := forms.NewGroup(
forms.Field("email", forms.Required(), forms.Email()),
forms.Field("password", forms.Required(), forms.MinLength(8)),
)
TextField("Email").Bind(form.Field("email"))
Button("Submit").Disabled(signals.Not(form.Valid()))3. Context DI (Infrastructure Only)Type-safe injection for Theme, Logger, Config, i18n. Business logic via explicit parameters. 4. Control Flow DSLDeclarative If/For/Switch builders alongside native Go control flow. Questions for Discussion
We want your feedback before finalizing these decisions! |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
|
Thank you for the first real-world feedback! This is exactly the kind of practical insight we need. You've identified a key ergonomics problem. The verbose Proposed SolutionsWe're considering several approaches that don't require go generate: 1. BindFormat helper // Instead of signals.Computed(func() string { return fmt.Sprintf(...) })
Text().BindFormat("Count: %d", count)2. Direct signal binding with auto-conversion // Widget accepts Signal[T] and converts automatically
Text().Bind(count) // int → string via fmt.Sprint3. Method chaining for conditional properties Button("Click").
Bind(count, "Count: %d").
DisabledWhen(signals.LessThan(count, 0)).
ClassWhen("highlight", signals.GreaterThan(count, 10))4. Computed shorthand // Helper for simple format cases
label := signals.Format("Count: %d", count)
Text().Bind(label)Our DirectionWe want to avoid go generate magic — it complicates debugging and IDE support. Instead, we'll provide ergonomic helpers for common patterns while keeping the explicit Question for you: Which approach feels most natural? Would |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
Hello. Is it possible to use functional options instead of fluent-like api? As far as I know gofmt doesn't really like multiline method chains and I find them pretty inconcinient to use in a single line with bigger fonts due to vision problems. Also struct options and similar to func options with-wrappers are most go-idiomatic way to build things in stdlib. |
Beta Was this translation helpful? Give feedback.
-
|
Hi @sedyh, thank you for the thoughtful feedback! If I understand correctly, you're suggesting we prioritize functional options over fluent/method-chaining APIs because:
These are excellent points that deserve careful consideration. Our Initial ResearchDuring architecture planning, we evaluated API approaches from both human and AI perspectives:
Fluent APIs scored well for both: humans get IDE autocomplete and linear reading, while AI agents generate fewer errors due to immediate compile-time feedback. Context Matters: When Fluent Works WellFluent API works well for builder patterns — it's simply convenient: // SQL query building (ozzo-dbx, relica)
db.Select("id", "name").
From("users").
Where(dbx.HashExp{"id": 100}).
One(&user)Methods can be called in any order (query generates at the end), and it's readable for both humans and AI. Your Points Add Important DimensionsFor widget construction, Go stdlib takes a different approach:
The 2026+ ConsiderationWe believe that in 2026 and beyond, many developers will transition to AI-augmented development workflows. This means we need to carefully balance:
Options We're ConsideringOption A: Functional Options Only (most Go-idiomatic) btn := ui.NewButton(
ui.WithText("Submit"),
ui.WithPadding(16),
ui.WithBackground(theme.Primary),
ui.WithOnClick(handleClick),
)
Option B: Hybrid Approach (construction + styling) // Construction: Functional Options
btn := ui.NewButton(
ui.WithText("Submit"),
ui.WithOnClick(handleClick),
)
// Styling: Fluent (like query builders)
btn.Padding(16).Background(theme.Primary).Rounded(8)
Option C: Config Struct (for many options) btn := ui.NewButton(ui.ButtonConfig{
Text: "Submit",
Padding: 16,
Background: theme.Primary,
OnClick: handleClick,
})
Our ApproachWe will carefully evaluate all approaches before deciding, considering:
We may end up with a thoughtful combination rather than a single approach. For example:
Thank you for raising the vision accessibility angle — this is exactly the kind of feedback that helps us build a better library for everyone. What would work best for your use case? Would you prefer pure functional options, or could the hybrid approach (Option B) work? |
Beta Was this translation helpful? Give feedback.
-
|
Hi @crsolver, I noticed you've been leaving similar comments across multiple platforms (GitHub, Dev.to, Reddit) under different accounts. That's unusual behavior for GitHub — first time I've seen this kind of cross-platform pattern here. What's interesting is that your first comment on Dev.to was actually a thoughtful question about retained-mode GUI and raylib. We had a constructive exchange there. Then somewhere along the way, "AI slop" and "clanker" became your contribution style. If you have genuine technical concerns — bring them as issues or PRs. That's how open source works. Criticize? Sure, but propose alternatives. Found a bug? Report it. Think the architecture is wrong? Show us a better approach. Or build your own ecosystem the way you think it should be done. That's the beauty of open source — you can fork, improve, or start fresh. 250K+ lines of working code is there for anyone to learn from, critique, or build upon. But commenting "AI slop" without any technical substance across multiple platforms isn't criticism — it's just noise. The door is open for real contributions. 🚪 |
Beta Was this translation helpful? Give feedback.
-
|
Does it support Android? |
Beta Was this translation helpful? Give feedback.
-
|
Hi @beikege, Short answer: not yet. Longer answer: Android support is technically feasible, but there are some fundamental challenges I want to be transparent about. Current StatusRight now gogpu supports Windows, macOS, and Linux (X11/Wayland). The GPU backends (Vulkan, GLES) could theoretically work on Android since the APIs exist there, but the platform layer (windowing, input, lifecycle) is the blocker. The CGO ProblemAfter researching this thoroughly, I found that all production Go graphics libraries — Gio, Fyne, Ebitengine — require CGO for Android. The reason is architectural:
This means:
There's no pure Go workaround for this. Even purego uses CGO internally on Android. gogpu's philosophy has been zero-CGO for easy cross-compilation. Adding Android would mean accepting CGO as an Android-only requirement. Potential Paths
Estimated EffortIf we go the CGO route:
Total: roughly 4-5 weeks of focused work. Current PriorityWe're stabilizing the desktop platforms first. Android is on the radar but not in the immediate roadmap. The ecosystem (wgpu, naga, gg) needs to mature before expanding to mobile. That said, I'm curious about your use case. Are you:
This would help me understand the demand better. |
Beta Was this translation helpful? Give feedback.
-
|
Update: After more research, I found a more elegant approach. Minimal Bootstrap ArchitectureInstead of ~2,000 lines of CGO (like Gio/Fyne), we could use a "minimal bootstrap" pattern: This preserves gogpu's "Pure Go" philosophy — only ~80 lines of C as a bridge, everything else remains Go. Why This WorksCGO is only mandatory for JNI callbacks (entry points from Java). Once we have the native window pointer, all GPU operations can use purego / goffi to call Vulkan directly. Additional Context
TimelineThis is still not immediate priority, but the minimal bootstrap approach makes it more feasible than I initially described. A PoC could be done in 1-2 weeks when we get to it. If you're interested in Android specifically, let me know your use case — it helps prioritize. |
Beta Was this translation helpful? Give feedback.
-
|
I've created a dedicated discussion for Android support: Android Support — Research & Community Interest Feel free to share your use case and follow updates there. |
Beta Was this translation helpful? Give feedback.
-
Ecosystem Update: Ready for gogpu/ui DevelopmentJanuary 30, 2026 Release SummaryWe've completed a major ecosystem integration that provides the foundation for
What This EnablesUnified Rendering InterfaceThe // gpucontext/texture.go
type TextureDrawer interface {
DrawTexture(tex Texture, x, y float32) error
TextureCreator() TextureCreator
}
type TextureCreator interface {
NewTextureFromRGBA(width, height int, data []byte) (Texture, error)
}This is the exact pattern needed for
Working ExampleSee app := gogpu.NewApp(gogpu.DefaultConfig().
WithTitle("GoGPU + gg Integration").
WithSize(800, 600))
var canvas *ggcanvas.Canvas
app.OnDraw(func(dc *gogpu.Context) {
if canvas == nil {
canvas, _ = ggcanvas.New(app.GPUContextProvider(), w, h)
}
ctx := canvas.Context()
ctx.SetRGB(1, 0, 0)
ctx.DrawCircle(400, 300, 100)
ctx.Fill()
// Render to gogpu window (one line!)
canvas.RenderTo(dc.AsTextureDrawer())
})Architecture for gogpu/uiWhat's NextWith these interfaces in place, we can now start
The ecosystem is ready. Let's build the UI toolkit! https://dev.to/kolkov/gogpu-unified-2d3d-graphics-integration-in-pure-go-djf Releases: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Overview
We are excited to announce gogpu/ui — an enterprise-grade GUI toolkit for Go, designed to enable building professional applications such as:
This RFC seeks community feedback on our architecture decisions and development roadmap before we begin Phase 1 implementation.
Key Differentiators
Architecture
Full architecture details: docs/ARCHITECTURE.md
Planned API
Development Roadmap
Full roadmap: ROADMAP.md
Versioning Strategy
We follow a conservative v0.x.x strategy:
/v2import path)Backward Compatibility Patterns:
internal/for implementation detailsexperimental/for unstable featuresFull policy: docs/VERSIONING.md
Architecture Update (December 25, 2025)
After conducting deep research on 7 leading Rust UI frameworks (GPUI/Zed, Xilem, Floem/Lapce, iced, egui, Slint, Dioxus) and analyzing modern UI patterns, we have finalized key architectural decisions:
Confirmed Design Decisions
Why Tailwind-style API?
We evaluated API ergonomics from both developer and AI coding agent perspective (Claude, Copilot, Cursor). Key findings:
Updated API Example
What We Decided NOT to Implement
Questions for the Community
We would appreciate feedback on the following:
1. API Design
2. Widget Priority
Which widgets are most critical for your use cases?
3. Theme System
4. Accessibility
5. Migration
Resources
Get Involved
We believe Go deserves an enterprise-grade GUI toolkit, and we are building it with the community input.
The gogpu team
Beta Was this translation helpful? Give feedback.
All reactions