The Tao backend
Tao is a Rust-native window backend that runs Compose Desktop without AWT and adds native Wayland, multi-touch, and pen input.
Tao is the Rust windowing crate that also underpins Tauri 2. Nucleus wraps it as a window backend: Compose Desktop renders into a native OS window, so there is no Swing event-dispatch thread and no XWayland fallback. Tao is the backend for new Nucleus apps. The legacy AWT backend is deprecated and will be removed in a future release — see migration from JBR.
Add the dependency
dependencies {
implementation("dev.nucleusframework:nucleus.nucleus-application:2.0.7")
implementation("dev.nucleusframework:nucleus.decorated-window-core:2.0.7")
implementation("dev.nucleusframework:nucleus.decorated-window-tao:2.0.7")
}The Nucleus Gradle plugin detects decorated-window-tao on the classpath and selects the
Tao backend at runtime. To select it explicitly, pass NucleusBackend.Tao:
nucleusApplication(backend = NucleusBackend.Tao) {
// …
}Create a window
import dev.nucleusframework.application.DecoratedWindow
import dev.nucleusframework.application.NucleusBackend
import dev.nucleusframework.application.nucleusApplication
import dev.nucleusframework.window.TitleBar
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.rememberWindowState
fun main() = nucleusApplication(backend = NucleusBackend.Tao) {
DecoratedWindow(
onCloseRequest = ::exitApplication,
state = rememberWindowState(size = DpSize(1024.dp, 720.dp)),
title = "Hello Tao",
) {
TitleBar { state -> /* custom title bar */ }
MyContent()
}
}DecoratedWindow and TitleBar are the same Composables across backends, so your UI code
does not change when you switch backends.
How it works
Tao opens a native OS window directly: an NSWindow on macOS, an HWND on Windows, and a
wl_surface (or an X11 window) on Linux. Compose renders into that surface through Skiko —
Metal on macOS, WGL on Windows, EGL on Linux. Nothing routes through Swing's event-dispatch
thread.
Compose Desktop's SwingPanel does not work on the Tao backend and crashes the app at
runtime. It requires an AWT/Swing window hierarchy that Tao never creates. Embed native
content with NativeView instead, or keep the AWT backend for
windows that still need Swing interop.
The OS event loop runs on the process main thread, so the macOS launcher needs
-XstartOnFirstThread. The Nucleus Gradle plugin adds it automatically for run and packaged
distributions. GraalVM native-image builds start on the main thread by default.
The nucleusApplication { } entry point hides the backend choice from UI code. On the Tao
backend the same window exposes an imperative TaoWindow handle underneath, which you reach
through nucleusWindow.unsafe.taoWindow when you need to call into the native crate directly.
API reference
The Tao-specific API lives in dev.nucleusframework.window.tao:
taoApplication { }— direct entry point. PrefernucleusApplicationfor backend portability.TaoWindow— imperative window handle. Reach it throughLocalTaoWindowornucleusWindow.unsafe.taoWindow.NativeView— embed a SwiftUI, WebView2, or GTK view in Compose.MacOSStyle— window chrome on macOS:Auto(modern Tahoe chrome on macOS 26+, classic chrome otherwise),Classic(the default), orModern.TaoCursorIcon,TaoTrackpadGesture,TaoTrackpadPhase,TaoMouseButton,TaoEventCode— input constants.TaoDeepLinkBridge.setSink { uri -> … }— deep link delivery.
decorated-window-jbr and decorated-window-jni are deprecated and will be removed in a
future Nucleus release. Keep one on the classpath and select the backend with
NucleusBackend.Awt only if you still need Swing / AWT interop during migration. See
migration from JBR.
What's next
- The decorated window — the
DecoratedWindowandTitleBarComposables on Tao. - Multi-touch and gestures — trackpad and touch events from
TaoWindow. - Wayland — native Wayland behavior and detection.
- Quickstart — build and run your first Nucleus app.