Overview
Asuka documentation
Asuka makes native apps in Go, for iOS, Android, macOS, Windows, Linux and the web. An app's interface is Go functions that return views; Asuka shows them with each platform's own widgets, and updates only the views that read a signal when it changes.
func Counter() ui.Node {
count := signal.New(0)
label := signal.Func(func() string {
return fmt.Sprintf("Count: %d", count.Get())
})
return ui.SafeArea(ui.Style{Align: ui.AlignCenter, Justify: ui.JustifyCenter},
ui.Text(label),
ui.Button(ui.ButtonProps{
Title: ui.Val("Add"),
Variant: ui.ButtonFilled,
OnPress: func() { count.Set(count.Peek() + 1) },
}),
)
}
func main() { app.Run(Counter) }How it works
Your app is Go: its components, its state and the rest of its code. Asuka's core runs the components, lays the views out (flexbox and grid, in Go), and sends what changed to the platform's host, in a batch for each frame. The host makes and updates the platform's own views:
| Platform | Host | Its views |
|---|---|---|
| iOS | Swift, with the app's Go built in as a library | UIKit |
| Android | Kotlin, with the app's Go built in as a library | Android Views and Material 3 |
| macOS | Go, in the app's process (AppKit through purego) | AppKit |
| Windows | Go, in the app's process (Win32 through syscall) |
Win32 and the common controls, drawn as Windows 11's |
| Linux | Go, in the app's process (GTK through purego) | GTK 4 and libadwaita |
| The web | JavaScript, with the app's Go as WebAssembly | The page's DOM and the browser's own controls |
A text field is a UITextField, an EditText, an NSTextField, an
EDIT control, a GtkEntry or an <input>; a stack of screens is a
UINavigationController, Material's app bar with its back gesture, the
Mac window's toolbar with its back button, or libadwaita's navigation
view. So an app that sets no style looks as the platform's apps do, and
gets their accessibility, text input and scrolling as they have them.
The desktop hosts call the system's libraries from Go, without cgo, so
a Windows or Linux app builds with Go alone, from any system.
Signals hold the state. A component runs once; when a signal changes, only the props that read it are sent again, without diffing a tree.
The same app runs everywhere. On a phone it fills the screen; on a
desktop it's a window the user resizes, and it can open more windows
(ui.Window, which a phone hasn't) and have a menu bar with
keyboard shortcuts (ui.MenuBar, ignored on a phone). A package for
something a platform doesn't have (sensors or home screen widgets on a
Mac) answers there that it isn't available, so the app can check and do
without.
Asuka needs Go 1.26 or later. Apps run on iOS 16, Android 13 (API 33),
macOS 11, Windows 10 and Linux with GTK 4.14 and libadwaita 1.5, and
later; and in current browsers. asuka dev runs your app while you work
and reloads it as you save: on the simulator, an emulator or a phone,
with your Go code on your computer; on the computer itself; or in your
browser.
Guides
asuka dev in depth on each platform,
devices, asuka vet, tests and common problems.ShippingBuilds for the App Store and Google Play, a
signed and notarized Mac app, a Windows folder, a Linux archive and
Flatpak manifest, and what asuka.json says of the app.The webThe same app in a browser, as WebAssembly and the
page's DOM; asuka dev --platform web, a static site to deploy,
embedding, and what it doesn't do yet.