Go language bindings for wxWidgets via kwxFFI, enabling cross-platform GUI applications that render with native controls on Windows, macOS, and Linux.
Do not use this Go/wxWidgets interface in production.
- The kwxFFI ABI interface is not stable and can change without warning.
- Very little testing has been done, and won't be until late Q2 of 2026.
- API surface may change as idioms are refined.
kwxGO provides a two-layer binding architecture:
- FFI Layer (
wx/cgo_*.go) — Raw CGo declarations with// #includedirectives mapping directly to the kwxFFI C function exports. All pointers areunsafe.Pointer. - Wrapper Layer (
wx/*_gen.go) — Idiomatic Go wrappers with proper types, automatic string conversion, and sensible defaults.
Users should work with the wrapper layer. The FFI layer is available for direct access when needed.
Go code → CGo (unsafe.Pointer) → kwxFFI (C functions) → wxWidgets (C++)
// examples/minimal/main.go - Minimal wxWidgets application in Go
package main
import (
"github.com/KeyWorksRW/kwxGO/wx"
)
func main() {
wx.Run(func() bool {
// Create main frame
frame := wx.NewFrame(nil, wx.ID_ANY, "Hello wxGO",
-1, -1, 400, 300, wx.DEFAULT_FRAME_STYLE)
// Create panel to hold controls
panel := wx.NewPanel(frame.Ptr(), wx.ID_ANY,
-1, -1, -1, -1, 0)
// Create a button
button := wx.NewButton(panel.Ptr(), wx.ID_ANY, "Click Me!",
50, 50, -1, -1, 0)
// Bind button click event
button.Bind(wx.EVT_BUTTON, func(evt *wx.Event) {
wx.MessageBox("Hello from Go!", "wxGO",
wx.OK|wx.ICON_INFORMATION, frame.Ptr(), -1, -1)
})
// Show the frame
frame.Show()
wx.SetTopWindow(frame.Ptr())
return true
})
}More examples are in the examples/ directory.
Types mirror the wxWidgets C++ class hierarchy using Go struct embedding:
BaseObject
└── EvtHandler
└── Window
├── TopLevelWindow
│ ├── Frame
│ └── Dialog
├── Control
│ ├── Button
│ ├── StaticText
│ ├── TextCtrl
│ ├── CheckBox
│ ├── RadioButton
│ ├── Choice
│ ├── ListBox
│ ├── ComboBox
│ └── BitmapButton
└── Panel
BaseObject
└── Sizer
├── BoxSizer
├── FlexGridSizer
└── GridSizer
All types wrap an opaque unsafe.Pointer via BaseObject with a Ptr() accessor.
| Entity | Convention | Example |
|---|---|---|
| Package | wx |
import "github.com/KeyWorksRW/kwxGO/wx" |
| Types | PascalCase |
Frame, Button, Window |
| Constructors | New<Type> |
NewFrame(), NewButton() |
| Methods | PascalCase |
frame.SetTitle(), btn.SetLabel() |
| Constants | UPPER_SNAKE |
DEFAULT_FRAME_STYLE, ID_ANY |
| Event types | EVT_* |
EVT_BUTTON, EVT_MENU |
Go's native compilation, goroutine model, and growing use in systems and tooling make it attractive for desktop GUI applications. kwxGO provides native-look cross-platform GUIs with static linking — one executable, no runtime dependencies.
| Tool | Minimum Version |
|---|---|
| Go | 1.22 |
| CMake | 3.30 |
| Ninja | any recent |
CGo on Windows uses the MinGW-w64 linker, which is incompatible with the MSVC object format and ABI. You must use one of:
| Toolchain | Preset | Notes |
|---|---|---|
| GCC (MinGW-w64) | ninja-gcc |
Install MSYS2 → pacman -S mingw-w64-ucrt-x86_64-gcc |
| Clang (MinGW target) | ninja-clang |
Install LLVM-MinGW or MSYS2 → pacman -S mingw-w64-ucrt-x86_64-clang |
Why no MSVC? Go's CGo toolchain links using a MinGW-hosted GCC. It cannot consume
.libfiles produced bycl.exe. A static library built with GCC or MinGW-targeted Clang produces a.aarchive that CGo can link directly, with no DLL dependency at runtime.
Prerequisites:
- Go 1.22+
- CMake 3.30+
- A supported C/C++ compiler (see above)
- Internet access for FetchContent (kwxFFI and wxWidgets are fetched automatically)
Apache License 2.0 — see LICENSE for details.