Nucleus
Compare

Nucleus vs Electron

Chromium and a Node bridge, or native Skia and a single Kotlin process.

Electron got the world to ship desktop apps in JavaScript by paying a tax — a Chromium per app, two runtimes per process, IPC between renderer and main, RAM measured in hundreds of megabytes. Nucleus is the inverse trade: keep the developer ergonomics, drop the Chromium, run one Kotlin process from UI to OS.

TL;DR

  • One language vs four. One process vs renderer + main + IPC bridge.
  • Native Skia renderer instead of Chromium — cold start in ~0.5 s, RAM in ~60 MB (GraalVM).
  • Auto-update, code signing, sandboxing, 16 packaging formats — all parity with electron-builder, none of the JS context switch.
  • Loses on hiring pool and ecosystem age. Electron has the deepest desktop JS community.

How they stack up

NucleusElectron
LanguagesKotlinJS + Node + native modules
RendererCompose UI + Skia GPUChromium (Blink + V8)
Process modelSingle processRenderer + main + IPC
Native APIs30+ Kotlin modules, in-processNode child_process / native modules
OS chromeDecorated windows: Liquid Glass, Fluent, Yaru, JewelChromium-style chrome
Cold start~0.5 s (GraalVM) · ~1.0 s (JVM+AOT)2–3 s
RAM idle60–150 MB200–500 MB
Binary size38 MB (GraalVM) · ~120 MB (JVM)150–200 MB
Auto-updateBuilt-in (updater-runtime)electron-updater (mature)
Packaging16 formats from one DSL5–7 via electron-builder
EcosystemJVM (Maven Central, ~500k libs)npm

The Chromium tax

Electron ships an entire browser per app because that's the only way to render web content with the consistency JS devs expect. The cost: every Electron app pays for V8, Blink, Skia, plus a Node runtime, all linked into the process tree. Six Electron apps idle on your machine and you're at 3 GB of RAM before doing anything.

Nucleus renders Compose UI directly to Skia via the Compose Multiplatform Skiko backend. No Blink, no V8, no Node. The JVM runs your code; Skia GPU paints the pixels. Everything lives in a single process, sharing one heap. The performance ceiling is the JVM's — and on hot paths the JVM matches C++ throughput once HotSpot warms.

The IPC bridge tax

Electron's renderer can't touch the OS — for that it sends messages over ipcRenderer / ipcMain. Every read of a file, every system tray click, every notification, crosses a serialization boundary. Type safety stops at the wire. You add layers of contextBridge wrappers, you debug across two devtools windows, you maintain two halves of every feature.

In Nucleus, your Compose UI calls NotificationManager.send(...), GlobalHotKeyManager.register(...), or SystemInfo.cpuInfo() directly. Same call graph, same coroutine, same debugger.

Native window decorations

Electron windows look like Chrome. To pass for native, you fight Chromium chrome — custom frames, vibrancy, draggable regions encoded as CSS. Nucleus's decorated window layer renders the title bar inside Compose with four toolkits:

  • macOS — Liquid Glass on SDK 26+, automatic via vtool patching.
  • Fluent — Windows 11 acrylic, snap-layout hints, mica.
  • Yaru — Ubuntu-native button layout that reacts to GNOME settings live.
  • Jewel — IntelliJ Platform look.

Bring your own design system on top — Material 2/3 adapters ship out of the box.

Where Electron still wins

  • Hiring pool. Everyone knows JS. Fewer know Kotlin Multiplatform desktop.
  • Ecosystem age. Electron has shipped VS Code, Slack, Discord, Figma, Notion. Battle scars accumulated for a decade.
  • Web reuse. If your product is already a single-page app, wrapping it in Electron beats rewriting in Compose for v1.
  • Node libraries. npm's surface area is larger than any single JVM library category — though the JVM dwarfs npm in numerical library count (~500k Maven Central artifacts).

Where Nucleus pulls ahead

  • One language, one mindset, one debugger. UI, business logic, OS calls, packaging — all Kotlin, all the same call graph.
  • Native rendering — your app doesn't look like a website pretending to be an app.
  • Two runtimes (GraalVM Native Image · JVM + AOT cache) from the same source — see performance.
  • 16 packaging formats vs 5–7 — see packaging comparison.
  • The full JVM library catalog runs in-process. Apache Lucene, DuckDB, ONNX Runtime, Tika, Netty, Spark — all implementation away, no native bridge.

When to pick Electron

You're a JS team shipping a v1, your product already exists as a web app, and your RAM/perf budget can absorb the Chromium tax. Or you have an existing Electron codebase and the migration cost outweighs the ongoing tax.

When to pick Nucleus

You want one language end-to-end, native rendering, store-ready packaging, and the JVM ecosystem in-process. You ship to enterprise networks where corporate root CAs matter and native-ssl saves you a quarter of incidents. You care about cold start enough to wire GraalVM Native Image.

Notes

[FACT-CHECK NEEDED] on Electron's exact RAM/cold-start numbers — they vary heavily by app. The 200–500 MB / 2–3 s range is a typical "Hello World + small SPA" envelope from public benchmarks.