MyGo
Desktop apps in Go, with a web frontend or a native UI.
Each MyGo window shows one of two kinds of interface, and one app can mix them:
- A web page, in the webview the OS already has: WKWebView on macOS,
- Native UI, written in Go alone with package
uiand
Either way, an app is a single Go binary of a few megabytes, focused on low memory and CPU use.
- Pure Go, no cgo: build for every platform from any machine.
- Typed IPC for pages: bind Go services, stream values through channels
- A Go UI toolkit for native UI: flexbox and grid layout, widgets, text
- Desktop APIs for both: windows, menus, tray, dialogs, notifications,
- Ready to ship: app bundles and disk images, Windows installers, Debian
A window with a web page, whose frontend calls Go:
type Greeter struct{}
// Greet returns a greeting.
func (Greeter) Greet(name string) string { return "Hello, " + name }
func main() {
mygo.Bind(Greeter{})
mygo.App.WhenReady(func() {
mygo.NewWindow(mygo.WindowOptions{Title: "Hello", URL: "/"})
})
if err := mygo.App.Run(); err != nil {
log.Fatal(err)
}
}
import { Greeter } from "./mygo"; // generated
document.body.textContent = await Greeter.greet("Ada");
A window with native UI, whose view is a Go function of the app's state:
type counter struct{ n int }
func (s counter) view(c ui.Context) {
ui.Column(c).Fill().Center().Gap(12).Children(func() {
ui.Text(c, fmt.Sprint(s.n)).FontSize(40).Bold()
if ui.PrimaryButton(c, "Increment").Clicked() {
s.n++
}
})
}
func main() {
s := &counter{}
mygo.App.WhenReady(func() {
mygo.NewWindow(mygo.WindowOptions{
Title: "Counter",
Content: ui.View(s.view),
})
})
if err := mygo.App.Run(); err != nil {
log.Fatal(err)
}
}
Getting started
With Go 1.27+ and Bun, create an app with a web frontend:
bunx mygo-cli init my-app # or: npx mygo-cli init my-app
cd my-app
bun run dev
An app of native UI needs Go alone:
go run github.com/egoist/mygo/cmd/mygo@latest init -template native my-app
cd my-app
go tool mygo dev
Read the documentation.
License
MIT