Real cross-platform — not just macOS, Windows and Linux, but the same Kotlin codebase as your Android, iOS and web apps. One language, every screen, every architecture.
On Android, Kotlin and Compose are first-class citizens. On iOS, Kotlin/Native reaches every UIKit and Foundation API while Compose renders like a true native app. On the web, Kotlin/JS and Wasm draw Compose UIs with the full browser API surface. Desktop had only half of that — you could render a window, but reaching the OS meant juggling pointers, compiling native libraries per platform, wiring JNI or FFM bridges, and learning a different native API for every OS — a wall most Kotlin developers couldn't climb. Nucleus closes the gap.
Write your UI once in Compose, render it in the desktop style of your choice — macOS, Windows 11 Fluent, Ubuntu Yaru, or IntelliJ Jewel. Each toolkit ships with a matching DecoratedWindow. macOS and Yaru are made by Nucleus; Jewel is JetBrains' official toolkit (the go-to for cross-platform IDE-like apps); Fluent comes from the open-source community.
Same Kotlin code, two runtimes: a GraalVM native image for instant cold start and a tiny resident set, or a modern JDK with AOT cache where HotSpot's JIT gets close to C++ and Rust on hot paths. Same source. Same build.
Instant cold start. Tiny footprint.
Your whole app is AOT-compiled to a standalone binary. No JVM startup, no class loading — the process is alive in half a second. Smallest resident set on the market.
nucleus.graalvm-runtimePeak JIT throughput. Plugins, agents, full reflection.
HotSpot's C2 JIT is the most mature compiler ever built. JDK 25's AOT cache primes class metadata so you skip the warm-up — and you keep everything closed-world gives up: dynamic class loading, full reflection, JVM agents, scripting engines, live plugins and extensions.
nucleus.aot-runtimeWin32 ITaskbarList3. NSUserNotifications. freedesktop D-Bus. IOKit. ScreenCaptureKit. Each desktop API is its own tiny ordeal — different language, different threading model, different conventions. Nucleus wraps every one in a Kotlin function that feels obvious. The result: a cross-platform abstraction simpler than the original, on every platform.
1// SwiftUI app (2025) — still goes through UserNotifications + UNNotificationCenter2import SwiftUI3import UserNotifications45@main6struct MyApp: App {7 @UIApplicationDelegateAdaptor(NotifDelegate.self) var delegate8 var body: some Scene { WindowGroup { ContentView() } }9}1011func postBuildNotif() async {12 let center = UNUserNotificationCenter.current()1314 // 1. Authorization15 let ok = try? await center.requestAuthorization(options: [.alert, .sound])16 guard ok == true else { return }1718 // 2. Declare the actions and register the category up-front19 let reveal = UNNotificationAction(identifier: "REVEAL",20 title: "Reveal in Finder", options: [.foreground])21 let copy = UNNotificationAction(identifier: "COPY",22 title: "Copy path", options: [])23 let share = UNNotificationAction(identifier: "SHARE",24 title: "Share…", options: [.foreground])2526 let cat = UNNotificationCategory(identifier: "BUILD_DONE",27 actions: [reveal, copy, share], intentIdentifiers: [],28 options: .customDismissAction)29 center.setNotificationCategories([cat])3031 // 3. Build content32 let content = UNMutableNotificationContent()33 content.title = "Build complete"34 content.body = "Installer ready. What now?"35 content.categoryIdentifier = "BUILD_DONE"36 content.sound = .default3738 let req = UNNotificationRequest(identifier: UUID().uuidString,39 content: content, trigger: nil)40 try? await center.add(req)41}4243// 4. Delegate to receive callbacks (must be retained, AppDelegate is easiest)44class NotifDelegate: NSObject, UIApplicationDelegate,45 UNUserNotificationCenterDelegate {46 func application(_ a: UIApplication, didFinishLaunchingWithOptions o:47 [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {48 UNUserNotificationCenter.current().delegate = self49 return true50 }5152 func userNotificationCenter(_ c: UNUserNotificationCenter,53 didReceive r: UNNotificationResponse,54 withCompletionHandler done: @escaping () -> Void) {55 switch r.actionIdentifier {56 case "REVEAL": revealInFinder(file)57 case "COPY": copyPath(file)58 case "SHARE": shareSheet(file)59 case UNNotificationDismissActionIdentifier:60 telemetry.log("notif_dismissed")61 default: break62 }63 done()64 }65}66// + Info.plist NSUserNotificationsUsageDescription67// + handle authorization revoked mid-app-lifecycle1import dev.nucleusframework.notification.notify2import dev.nucleusframework.notification.NotificationAction34notify(5 title = "Build complete",6 body = "Installer ready. What now?",7 icon = Icon.AppIcon,8 actions = listOf(9 NotificationAction("reveal", "Reveal in Finder") {10 Desktop.open(file.parent)11 },12 NotificationAction("copy", "Copy path") {13 Clipboard.put(file.absolutePath)14 },15 NotificationAction("share", "Share…") { shareSheet(file) },16 ),17 onDismiss = { telemetry.log("notif_dismissed") },18)Nucleus ships reusable GitHub Actions that build, sign, notarize, bundle and publish for every desktop — without a copy-pasted YAML in sight. Six composite actions, one reference workflow, one tag push.
git push tag v1.0.0setup-nucleusJBR 25 or Liberica NIK, Gradle cache, Node, Linux packaging tools — one step, every runner.
setup-macos-signingTemporary keychain, .p12 imported from secrets, identities exposed to downstream steps.
build-macos-universallipo merge arm64 + x64, inside-out re-sign, notarize via notarytool, staple — one DMG out.
build-windows-appxbundleMerge amd64 + arm64 .appx into a .msixbundle, sign with SignTool — Microsoft Store ready.
generate-update-ymlSHA-512 every installer, emit latest-mac.yml / latest.yml / latest-linux.yml for the auto-updater.
publish-releasegh release create with the right assets, marks -alpha / -beta / -rc as pre-release automatically.