Desktop & mobile apps
A Rat app is already a Go HTTP server with SSE reactivity. "Desktop" and "mobile" are not new runtimes. They run that same server on a 127.0.0.1 loopback port and point an OS-native webview at it. Same renderer, same eval-free runtime, same routing, same services. The web / desktop / mobile choice is a build target, never a source edit: your main.rat and settings.rat are untouched, so every app is already all three.
Run as a desktop window
rat start app
rat start app boots the runtime on a random loopback port and opens a native window onto it. The default build is cgo-free: it launches an installed Chromium browser in app mode (chromeless, throwaway profile). A -tags desktop build swaps in a single-process embedded webview instead. Either way you get a real window with no source changes.
# from your app directory
rat start app
# tune the window in settings.rat
> desktop
title: 'My App'
width: 1100
height: 760
resizable: true Build a distributable desktop binary
rat build desktop
rat build desktop emits one self-contained executable. The default is the cgo-free browser-app window - nothing to install on the target machine beyond an existing browser. Add --webview for the single-process embedded-webview variant (needs a C toolchain at build time and the platform webview runtime: WebView2 on Windows, webkit2gtk on Linux, system WebKit on macOS).
rat build desktop # cgo-free browser-app window
rat build desktop --webview # embedded webview (-tags desktop) Build an Android APK
rat build apk
rat build apk stages an Android shell, drops in a gomobile-bound library carrying the whole Go runtime + sqlite, embeds your app as assets, and produces an installable .apk - one command from any app directory. The server runs in-process behind a system WebView; routing, reactivity, services, and SSE ride loopback HTTP exactly as on web and desktop. Add --install to push it to a connected device.
rat build apk # builds <name>.apk
rat build apk --install # build + adb install to a device Branch on the target when you need to
env.desktop / env.mobile
The same source runs everywhere, but sometimes you want a touch-first layout on mobile or a different affordance on desktop. The env global exposes the resolved target for progressive enhancement. Reach for it only for genuine UX differences - the substrate already works on every target without it.
> page
(env.mobile)
<p> Tap and hold to share.
(env.desktop)
<p> Right-click for the context menu. Desktop and mobile share one capability story - the built-in native services (files, notifications, share, tray) that degrade cleanly from a native API to a web surface. Release signing and the app stores (Authenticode, notarization, Play Console, App Store) are the remaining packaging work; the engineering above is ready for them.
See also Native services · CLI · Channels