[RFC] gogpu/ui — Enterprise-Grade GUI Toolkit for Go #18
Replies: 17 comments 13 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! |
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 |
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. |
|
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? |
|
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. 🚪 |
|
Does it support Android? |
|
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. |
|
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. |
|
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. |
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: |
|
This project is fascinating to me, as someone who has previously written a golang vulkan library, and someone who currently owns a 2D/3D CAD project written in C++, I have lots of background doing golang development and deeply miss it and it's tooling, but also I recognize that AI assisted programming is the future. I wish I could have written my CAD software in golang and gogpu offers that potential. I think the "Smart Coding" approach is also potentially a major accelerator and a major risk. My challenge with my current CAD software is that AI face plants on helping me with it, due to the tech stack I'm using, C++ and the overall complexity - resulting in my current velocity being pretty poor. I've been playing with having AI write GUI desktop apps for me and I can see that the specific GUI library can have a big impact on the velocity and context usage of the AI agents. I can pretty much ask for complex QT6 apps and get what I want, out of Qwen3.6-27B, but I can't ask for a complex fyne.io app because the AI uses up all it's context just trying to learn how to use the framework. I'm OK with @kolkov's approach with gogpu/ui - although now that I've sat down and played with the example apps it's clear to me for this to be a usable project a bunch of humans are going to have to sit down and scrutinize the actual UI experience as it still has lots of problems - this is an area I believe requires deep coordination with humans and AI - it's hard for AI to understand why a UI interaction feels bad. Anyways this project holds a lot of potential - but also a lot of risk but it's going to require humans to be in the loop for testing to tell the AI what needs to be improved with the UI experience. What I would like to do is try to adopt @kolkov "Smart Coding" approach and try a reboot of my CAD software utilizing gogpu - but I don't think I could do this without other humans involved in growing gogpu/ui, et al to be more mature, and without also more time learning about how to apply "Smart Coding" to my approach. I did vibe code the start of a scene tree for my CAD software using gogpu/wgpu - which went OK and I see the potential. |
|
@celer Thank you for the thoughtful analysis -- and welcome! Your background (Vulkan library + 2D/3D CAD in C++) is exactly the kind of perspective we need. You're right that humans in the loop are essential for UI polish. Good news: we've recently assembled a small team of contributors and testers: Active contributors:
Active testers/reviewers:
The lower-level libraries (wgpu, naga, gg, gpucontext) are now stable enough -- today we shipped v0.36.1 with unified xkbcommon for proper international keyboard support. So the foundation is solid and we're actively shifting focus to Your CAD use case is very relevant -- @joeblew999 is in a similar space. The 3D scene tree via gogpu/wgpu is the right starting point, and once Re: "Smart Coding" -- happy to share more about the workflow if useful. The key insight: AI does bulk coding, humans validate behavior and UX. Exactly what you described. |
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
All reactions