We’re allergic to lying in tables, so here’s the honest map. Bunmaska implements ~21 of Electron’s main-process modules - about 70-80% of what a typical webview app actually uses - and now ships on three platforms: macOS (AppKit + WKWebView), Linux (GTK 4 + WebKitGTK 6), and Windows (WinCairo WebKit + Win32). No bundled Chromium on any of them.
Support is not uniform across platforms, and we won’t pretend it is. The table below is the source of truth.
Legend: full · partial (see notes) · engine-blocked (the WebKit build lacks the API) · not implemented.
The matrix
| Module | macOS | Linux | Windows | Notes |
|---|---|---|---|---|
app | Lifecycle, paths, single-instance, locale. Dock/badge are macOS-only and no-op elsewhere (as in Electron); the about panel works on macOS and Linux (GTK about dialog), no-op on Windows. activate/open-url/open-file fire on macOS only. The single-instance lock is unverified on Windows. | |||
BrowserWindow | getBounds/setBounds/setPosition are real frame geometry in global top-left coordinates on macOS (read from the window server) and Windows; the move event fires on macOS only. Linux leaves placement to the compositor (GTK4/Wayland): setPosition is a no-op, setBounds applies size only, getBounds reports x/y as 0, and minimize/restore never fire (GTK4 exposes no minimized state). Windows setMinimumSize is a no-op (needs WM_GETMINMAXINFO). | |||
webContents (core) | load/navigation/executeJavaScript/zoom/insertCSS/IPC send everywhere. setWindowOpenHandler({action:'allow'}) is unimplemented on all three (window.open is blocked by default); on Windows the handler callback is not invoked yet. | |||
webContents.printToPDF | macOS via createPDFWithConfiguration. Linux: not yet wired. Windows: engine-blocked (no PDF sink in the WinCairo C API). | |||
webContents.capturePage | macOS via WKWebView snapshot, Linux via webkit_web_view_get_snapshot (visible viewport, PNG). Windows: engine-blocked (no UI-process snapshot). | |||
webContents.sendInputEvent | Trusted input synthesis - the page sees isTrusted === true, which a script-dispatched event can’t. Windows only (WinCairo, via posted/sent Win32 messages); macOS + Linux throw UnsupportedPlatformError. Windows follow-ups: no keyboard modifiers, synthesized drags don’t carry button state, KeyboardEvent.code/scan-codes and F1-F24 aren’t wired, and coordinates are correct at 100% display scale only (per-monitor DPI pending). | |||
ipcMain / ipcRenderer | handle/on/invoke/send. | |||
contextBridge | Real isolated content world on macOS/Linux. Windows runs in the page world (WinCairo exposes no named world) - the bridge works, but the isolation guarantee is weaker. | |||
Menu / MenuItem | Context menus + application menu bar on all three. macOS routes roles to the responder chain; Linux wires the editing and window roles; Windows role items are inert labels today (no accelerator table). Accelerator text in labels is a follow-up off macOS. | |||
dialog | Linux: openDirectory/multiSelections ignored, severity is a no-op. Windows: custom button labels approximated (native MessageBoxW button sets). | |||
clipboard | text / HTML / image on all three. Reads are async everywhere (GDK requires it). | |||
Tray | Linux: SNI tray, gated behind BUNMASKA_ENABLE_LINUX_TRAY, no context menu yet. Windows: icon + tooltip + left-click, context menu deferred. | |||
Notification | macOS delivers only from a real .app bundle (isSupported() is honest about it); click/close events not wired. Linux: close event only. Windows: balloon toast (rich toasts are a follow-up) that fires close on dismissal. silent works on all three. | |||
nativeImage | path/buffer/dataURL/PNG/JPEG/resize/crop. JPEG quality is honored on macOS only. | |||
nativeTheme | macOS: read + themeSource override + live updated. Linux: read + live updated, but themeSource is TS-only (no native re-theme). Windows: read + themeSource (TS-level); live observation is a follow-up. | |||
globalShortcut | Linux: X11 only (isSupported() is false under Wayland). | |||
shell | openExternal/openPath/showItemInFolder/beep. Linux showItemInFolder opens the parent folder without selecting. | |||
protocol | Custom scheme handlers serve on macOS/Linux. Windows: engine-blocked - the WinCairo C API exposes no scheme-handler entry point. | |||
screen | Display enumeration + scale factor work everywhere. Windows has a real getCursorScreenPoint and work area; on macOS/Linux both are stubbed (cursor {0,0}, workArea = bounds) - a bun:ffi struct-return limitation - and rotation is approximated. | |||
powerMonitor | suspend/resume + lock/unlock on all three. getSystemIdleTime/isOnBatteryPower not implemented on any. Linux is gated behind BUNMASKA_ENABLE_LINUX_POWER. | |||
powerSaveBlocker | Linux: gated, and both blocker types map to screensaver inhibition. | |||
safeStorage | macOS Keychain, Windows DPAPI. Linux: libsecret, gated behind BUNMASKA_ENABLE_LINUX_KEYRING (no plaintext fallback - encrypt/decrypt throw when unavailable). | |||
session | getUserAgent/setUserAgent everywhere. cookies (get/set/remove) on macOS + Linux; macOS cannot persist httpOnly (no public NSHTTPCookie key); Windows is engine-blocked (the WinCairo C API exposes no cookie read/write). clearStorageData: macOS clears all website data; Windows clears cookies + fetch caches; Linux not yet wired. | |||
autoUpdater | Signed updates end to end: check/download, Ed25519 signature + hash verification (unsigned feeds refused), stage, and a real detached swap-and-relaunch installer on all three OSes. Honest residue: the live swap is the one step CI doesn’t exercise end to end, it refuses non-installed layouts (dev runs), and the installer stays injectable. | |||
accelerator · app-paths · requestSingleInstanceLock | Pure or fully-wired on all three. |
Engine-blocked - why these can’t ship on a given OS
These aren’t laziness; the OS’s WebKit simply doesn’t expose the API:
- Windows
protocol/printToPDF/capturePage- the WinCairo WebKit2 C API has no custom-scheme-handler, no PDF sink (WKPageDrawPagesToPDFis Cocoa-only), and no UI-process snapshot (only the web-processWKBundlePage*variants). We confirmed each by parsingWebKit2.dll’s export table. They become available only if upstream WinCairo adds them.
Pending (inside shipped modules)
Real gaps we’re actively filling: session.clearStorageData on Linux; session.cookies httpOnly persistence on macOS; richer webContents events; the Windows setWindowOpenHandler callback; live nativeTheme observation on Windows; tray context menus on Linux/Windows; BrowserWindow.setMinimumSize and the move event off macOS; the isolated content world on Windows.
Out of scope by design
Chromium-internal surfaces - not coming, and that’s deliberate:
BrowserView / WebContentsView (single-process) · desktopCapturer · net / netLog · webRequest / proxy · crashReporter · contentTracing · utilityProcess · TouchBar · inAppPurchase · extensions · pushNotifications · Web Serial / WebHID / WebUSB.
If a cell you need is , , or in “pending,” now you know - before you’ve ported half your app. That’s the whole reason this page exists.