Desktop apps on Bun + WebKit

Build an app before you finish your bun-maska & chai.

A drop-in Electron replacement - the same APIs, none of the Chromium. Tiny downloads, native modules that are just .ts files, and a laptop fan that finally gets a rest.

bun add bunmaska

Alpha - and we'll admit it. macOS + Linux.

No logos of companies we can't name yet. Just the truth: it's open, it's built on Bun + WebKit, and it's early.

zero runtime deps zero compiled code MIT

The whole thing

~16 MB. Yes, all of it.

Electron asks for 150 MB+ before it's done anything. Bunmaska is the download you won't notice and the app you can't hear running.

A minimal Electron app 150 MB+
The same app, on Bunmaska ~16-23 MB

Same app. One bundles a whole browser; the other just doesn't.

~16-23 MB
download
~60 MB
installed
0
runtime deps
0
compiled native code

The part worth paying attention to

A native module is just a .ts file.

It dlopens the OS and gets on with its life. No node-gyp. No N-API. No electron-rebuild. No 40-minute compile that fails on the one machine that matters.

Nothing to rebuild, because there was never anything to build.

notify.ts
// notify.ts - a native module. No build step. No bindings.gyp. Just Bun.
import { dlopen, FFIType } from "bun:ffi";

const { symbols: libc } = dlopen("libc.so.6", {
  getpid: { args: [], returns: FFIType.i32 },
});

export const pid = () => libc.getpid();

The Electron version of this starts with npm install node-gyp and ends with a Stack Overflow tab. We skipped to the end.

Built on WebKit, not Chromium.

Your apps render on WebKit instead of a bundled browser. No Chromium shipped - ever.

Pure bun:ffi

Zero compiled native code. Zero runtime deps. The whole framework is TypeScript calling the OS.

WebKit, not Chromium

Renders on WebKit - WKWebView on macOS, WebKitGTK on Linux. No browser engine bundled into your app.

Electron-shaped API

app, BrowserWindow, ipcMain, Menu, Tray, dialog… the names you already know. Drop-in shim included.

A real CLI

bunmaska init / dev / run / build. Scaffold, hot-reload, and package to .dmg or .deb.

macOS + Linux

Two platforms that actually work. Windows is on the list, not in the build. We'll be honest about it.

Fast cold start

No Chromium to boot, no V8 snapshot to thaw. Bun + JavaScriptCore, up before your splash screen would've loaded.

When "works on my machine" isn't enough

Pin the WebKit you actually tested.

By default you render on the system's WebKit - that's why the apps are tiny. When you'd rather ship the exact build you tested, pin it. The app resolves that engine from a shared store, downloaded once and shared by every app. Different apps can pin different versions, side by side. No global switch.

bunmaska.config.ts
import { defineConfig } from "bunmaska/config";

export default defineConfig({
  // Pin the exact WebKit you tested. Shared across apps. No global switch.
  engine: { webkit: "webkitgtk-6.0-2.52.4-bunmaska1-linux-x64" },
});

This is an opt-in, Linux-first tier today: pinning, the shared store, and the engine CLI work now. Downloadable prebuilt engines and full macOS + Windows support are on the way - Windows brings its own WebKit (WinCairo, never Chromium). Most apps never need it; it's here for when byte-for-byte consistency matters.

Two platforms that work, one we're honest about.

Bunmaska ships on macOS and Linux today - x64 and ARM. Windows isn't here yet, and we're not going to pretend it is: it's not truly cross-platform until Windows actually works.

Shipping

macOS

Apple Silicon (ARM64) · Intel (x64)

AppKit + WKWebView via objc_msgSend

Shipping

Linux

x64 · ARM64 - incl. Raspberry Pi

GTK 4 + WebKitGTK 6 (where WebKitGTK is available)

Planned

Windows

Not yet - on the roadmap

Planned via WinCairo WebKit. We will not ship Chromium.

Want Windows? So do we - track it on the roadmap.

Developer experience

From zero to a window in about ninety seconds.

bunmaska initbunmaska dev → a real window. Then bunmaska build → one executable you can hand someone. The other steps are optional, and so is your patience.

src/main.ts
import { app, BrowserWindow } from "bunmaska";

app.whenReady().then(() => {
  const win = new BrowserWindow({ width: 960, height: 720 });
  win.loadURL("https://example.com");
});

What ships is a standalone .app or .deb - your users double-click it. They never install Bunmaska or open a terminal. The CLI is your dev tool, not theirs.

One command

The whole loop is bunmaska.

Scaffold, develop, package, and manage engines - one CLI, pure Bun, no Xcode project and no electron-builder. It's your dev tool; it never ships inside your app.

Terminal
# scaffold · develop · package
bunmaska init my-app     # a full starter: main + preload + renderer + config
bunmaska dev             # run it, hot-reloading on save
bunmaska build           # a standalone .app / .deb your users double-click
bunmaska build --update  # ...plus the auto-update feed (update.json + .tar.zst)

# pin & manage the WebKit engine - the "tested == shipped" tier
bunmaska engine list     # what's installed, side by side
bunmaska engine which    # the engine this project resolves
bunmaska engine install  # a local dir, or a signed feed URL

# is everything wired up?
bunmaska doctor          # runtime, store, and the resolved engine

Most days you live in initdevbuild. The rest is there the day you need it. Full reference in the CLI docs.

Same shape. A tenth of the weight.

Electron Bunmaska
Download size 150 MB+ ~16-23 MB
Installed size ~220 MB ~60 MB
Rendering engine Bundled Chromium (every app, again) OS-native WebKit (not bundled)
Native modules node-gyp / N-API / electron-rebuild a .ts file that dlopens the OS
Compile step Yes, and it'll fail somewhere None
Runtime deps Several Zero
Runtime Node + V8 Bun + JavaScriptCore
Platforms Win / macOS / Linux macOS + Linux (Windows: not yet)
Familiar API The original Drop-in, ~70-80% parity

We left a few rows where Electron still wins. We're allergic to lying in tables too.

It's alpha. We're not going to pretend otherwise.

Things will move. Some things will break. We'll tell you which ones. If it's still 2027 and this still says alpha, open an issue titled "are you OK."

Windows?

macOS and Linux today. Windows is on the list, not in the build - we'd rather ship two platforms that work than three that sort of do. Windows folks: we see you. Hang tight.

Production-ready?

It says alpha for a reason. Use it for the thing you were going to rewrite anyway.

Why no Chromium?

Because it's already on your computer, and shipping a second one is how we got here.

What's the catch?

~70-80% of Electron's surface, and we publish the parity matrix so you can check before you commit.

What's the bigger picture?

Bunmaska is the foundation. We're also building Chai on top of it - an app store and launcher for genuinely small native apps. That's a separate thing for later; the framework comes first.

Same APIs. Hold the Chromium.

Try it in a weekend. Hate it by Monday, or don't.