Library / SDK
twgh/xcgui avatar
twgh/xcgui

xcgui: Go bindings for a DirectUI interface library

炫彩界面库. Go GUI library. Golang bindings for XCGUI, Windows GUI library, DirectUI design idea.

617 stars63 forksGoMIT

At a glance

What is it?
xcgui wraps the XCGUI C/C++ interface library for Windows with Go, giving a Go program DirectUI rendering, a visual designer and roughly two thousand API calls. It is fast and deeply native to Windows, and it commits you to one operating system.
Who is it for?
xcgui suits a Windows desktop product written in Go that needs a custom, non-standard look, hardware-accelerated drawing and a designer in the team's toolkit, and that is willing to depend on a native DLL. It does not suit a cross-platform application, since the underlying library is a Windows component.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the project wraps and what it adds

xcgui is a Go binding for the XCGUI interface library, the Chinese 炫彩界面库, and the repository description says so in plain terms: Go GUI library, Golang bindings for XCGUI, Windows GUI library, DirectUI design idea. The underlying library is written in C and C++, which the README explains is why it runs efficiently and needs no third-party support and does not depend on MFC, ATL or the Windows standard controls.@@P@@The binding layer is what a Go developer actually touches. The README describes the surface as close to two thousand API interfaces, feature-rich, simple to use, lightweight, highly customisable and supporting one-click skin changes. A Go module and a GoDoc reference sit alongside a Chinese and an English README, a user guide with tutorials and common questions, a companion repository of worked examples, and the upstream project site with official documentation and resources.@@P@@Two things are worth flagging before you go further. The first is that this is a binding, not a reimplementation, so the DLL has to be present at run time, and the Go package is a thin shell over a native library whose version the README flags separately as XCGUI 4.0. The second is platform: the library is a Windows component, so this is a Windows-only option no matter how portable your Go code otherwise is.@@P@@The module is installed with a single command.

bash
go get -u github.com/twgh/xcgui

The module path is github.com/twgh/xcgui and it declares Go 1.18, matching the badge in the README. The latest release is v1.4.3, published on 2026-10-19, following v1.4.2 on 2026-07-10 and v1.4.1 on 2026-06-09. The repository was last pushed on 2026-10-19 and is not archived, and the licence is MIT, kept in a file named xcgui license.txt at the root.

The DirectUI idea: logical regions instead of child windows

The design decision that shapes everything else is DirectUI. The README explains it in terms of what does not exist: inside a window there are no child windows, because the interface elements are logical regions with no HWND handles. That is described as safe and flexible. Every UI element is developed independently, not constrained by what the system provides.@@P@@The practical consequences run in both directions. You are not fighting the system theme, the standard controls and their quirks, so an application can look like nothing else on the machine, which is the point for tools, media players and kiosk interfaces. You also lose the things the system gives you for free: no native edit controls with their own accessibility support, no standard focus and caret behaviour inherited from the platform, and a rendering model where the application paints every pixel of every element itself.@@P@@The rendering backends are Direct2D with hardware acceleration, which the README presents as the way to get high performance and high quality 2D graphics and to make better use of the hardware. There is also WebView2 support, so an interface can be built with a frontend stack when a part of the product is better served by HTML than by drawn elements. The two together, drawn DirectUI for the shell and WebView2 for the content, is a common shape for this kind of toolkit.

Two ways to build a window: the designer or pure code

The README shows two paths, and the difference in the amount of code between them is the whole selling point of the designer.@@P@@The first example loads a layout that was designed visually. The resources are embedded in the binary with the go:embed directive, the UI library is initialised, the resource zip is loaded from memory, and a window is created from a layout file inside that zip.@@P@@

go
import (
	_ "embed"
	"github.com/twgh/xcgui/app"
	"github.com/twgh/xcgui/widget"
	"github.com/twgh/xcgui/window"
)

//go:embed res/qqmusic.zip
var qqmusic []byte

func main() {
    app.Init()
	a := app.New(true)
	a.EnableAutoDPI(true).EnableDPI(true)
	a.LoadResourceZipMem(qqmusic, "resource.res", "")
	w := window.NewByLayoutZipMem(qqmusic, "main.xml", "", 0, 0)
	song := widget.NewShapeTextByName("songTitle")
	println(song.GetText())
	w.AdjustLayout()
	w.Show(true)
	a.Run()
	a.Exit()
}

@@P@@Notice how little Go there is. The layout, the resource files and the visual structure live in the designer, and the code only wires the two together. The example then retrieves a named element, in this case a text element whose name attribute was set in the layout file, and reads its text, which demonstrates the bridge between the designed interface and the code that drives it.@@P@@The second example builds the same kind of window in pure code, with no designer involved.@@P@@

go
func main() {
    app.Init()
	a := app.New(true)
	a.EnableAutoDPI(true).EnableDPI(true)
	w := window.New(0, 0, 430, 300, "xcgui window", 0, xcc.Window_Style_Default|xcc.Window_Style_Drag_Window)
	w.SetBorderSize(0, 30, 0, 0)
	w.SetTransparentType(xcc.Window_Transparent_Shadow)
	btn := widget.NewButton(165, 135, 100, 30, "Button", w.Handle)
	btn.AddEvent_BnClick(func(hEle int, pbHandled *bool) int {
		w.MessageBox("提示", btn.GetText(), xcc.MessageBox_Flag_Ok|xcc.MessageBox_Flag_Icon_Info, xcc.Window_Style_Modal)
		return 0
	})
	w.Show(true)
	a.Run()
	a.Exit()
}

@@P@@The code path exposes the native options directly: window styles are combined with a bitwise or, the border is sized per edge, the transparent type and the shadow are configured with explicit parameters, a button is created at a position and size, and a click handler is attached that shows a message box. The DPI handling is explicit as well, with automatic DPI and DPI awareness enabled on the application object.@@P@@The designer itself is free and shipped separately, as the README's resource links point out, along with the help documentation. The layout files are ordinary XML, and the resource archive is loaded from memory at run time, which means the visual assets travel inside the binary rather than as loose files beside it.

Package layout and the two ways to call the library

The repository directories map onto the layers of the library: app for application-level setup and the run loop, window for window objects, widget for the element catalogue, imagex for image handling, font, svg and svgp for vector graphics, drawx and ani for drawing and animation, res for resources, tmpl and tf for templates, edge for edge cases and behaviour, ease for easing functions, adapter and common for shared helpers, bkmanager and bkobj for background and object management, objectbase for the base object model, and wapi for the Windows API surface.@@P@@The xc and xcc packages are the escape hatches, and the README is explicit about how they relate to the rest. The xc package contains every API of the underlying xcgui.dll, close to two thousand functions, so a developer who is not comfortable with the class-based wrappers can call the original functions directly. All of the library's structures are in the xc package as well. The xcc package holds the constants, with the usual large enumeration of window styles, message box flags and transparency modes, and the README's advice is to copy the constant name into the package documentation search box to see the related constants and their comments.@@P@@The practical advice in the README is that in some situations mixing the native functions from xc with the wrapped classes is more convenient, and that the wrapped classes live in the other packages. The recommendation to develop with GoLand is a practical one about navigation in a two-thousand-call surface rather than a technical requirement.

The callback limit that decides how you register events

The most technical detail in the README is also the one most likely to bite a user, and it comes down to how events are registered. All of the library's events are already defined in the various classes, in two forms whose names begin with AddEvent or Event. The README's guidance is to use the AddEvent form in general.@@P@@The reason is a hard limit. The event callbacks are created with syscall.NewCallback, and that method can only create roughly two thousand callbacks; going past it panics. The Event form creates a new callback every time it is registered with an anonymous function, so a loop that registers handlers repeatedly will silently consume the budget and eventually crash. The AddEvent form reuses the callback it created, which means anonymous functions can be used freely with no risk of exhausting the limit.@@P@@The execution order is worth knowing too. One event type can have several callbacks registered, and they run with the most recently registered callback first and the first registered last. A callback that does not want the event to travel further sets its pbHandled parameter to true, which is the interception mechanism.@@P@@The pairing of these two facts explains the recommended style. With AddEvent you can write per-instance closures that capture the object they belong to, and you can register as many as the widget count demands, without thinking about a global budget that is shared across the process.

Where xcgui fits and the case for a pure-Go toolkit

The strongest argument for this library is the combination of things a pure-Go toolkit does not give you at once: hardware-accelerated custom drawing, a designer that non-programmers can use, one-click skinning, and a native feel on Windows. For a media application, an internal tool with a distinctive look, or a product sold in a Windows-only market, that combination is hard to reproduce. The XUI project linked from the README goes further in that direction, described as shadcn-style custom-drawn components for xcgui, and the designer examples live in the companion repository.@@P@@The cost is the binding itself. Your application now needs the native runtime library present, the release notes of the upstream library and of the binding have to be tracked together, and the API you code against is large enough that reading the documentation becomes part of the work. The README even points readers at a dedicated tooling project for AI-assisted development, with the stated aim of avoiding hallucinated API calls, which is an admission of how wide the surface is.@@P@@The alternative is a pure-Go GUI toolkit, which trades the designer, the custom look and the native rendering for cross-platform support, a single language toolchain and a far smaller API. If your application must run on Linux or macOS as well, that trade is not close. If it only ever runs on Windows and you need the look and the designer, this binding is the stronger choice. The intermediate option, keeping the Go backend and putting the interface in a WebView2 layer, is also credible given that the library itself supports WebView2, and it puts your UI work in a stack your frontend people already know.

Editorial conclusion

xcgui suits a Windows desktop product written in Go that needs a custom, non-standard look, hardware-accelerated drawing and a designer in the team's toolkit, and that is willing to depend on a native DLL. It does not suit a cross-platform application, since the underlying library is a Windows component. Verify first that your Go version is 1.18 or newer, that the runtime DLL ships with your installer, and that you use the AddEvent form of event registration unless you have counted your callbacks against the limit.

Frequently asked questions

What is the xcgui Go package?

It is a Go binding for XCGUI, a Windows interface library written in C and C++. The binding exposes roughly two thousand APIs, supports Direct2D with hardware acceleration and WebView2, and is MIT licensed.

How do I install the xcgui package?

Run `go get -u github.com/twgh/xcgui`. The module declares Go 1.18, and the underlying XCGUI runtime library is version 4.0 according to the README badges.

What is the DirectUI design idea in xcgui?

There are no child windows inside a window. Interface elements are logical regions with no HWND handles, and every UI element is drawn by the library itself rather than being a system control, which the README describes as safe and flexible.

Should I use AddEvent or Event to register xcgui handlers?

Use AddEvent. Callbacks are created with syscall.NewCallback, which allows only around two thousand of them before panicking, and the Event form creates a new callback each time it is registered with an anonymous function. AddEvent reuses the callback, so anonymous functions are safe.

Can I build an xcgui interface visually instead of in code?

Yes. The project ships a free visual UI designer, and a layout is loaded from an XML file inside a resource archive, with the archive embedded into the binary using the go:embed directive. The designer and the help documentation are offered as separate downloads.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. twgh/xcgui on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/twgh-xcgui.svg)](https://hysenlabs.com/projects/twgh-xcgui)

Was this useful?