Electrobun
Electrobun is a framework designed for building ultra-fast, tiny, and cross-platform desktop applications using TypeScript. Leveraging the Bun runtime for the main process and native system WebViews (WebKit on macOS, WebView2 on Windows, WebKitGTK on Linux) for rendering, it offers a compelling alternative to Electron by drastically reducing bundle sizes (often around 12-64MB) and memory footprint, as it avoids bundling a full Chromium instance. The framework provides a complete TypeScript-first API for both main and renderer processes, including type-safe RPC for inter-process communication, and eliminates the need for languages like Rust (as seen in Tauri). It boasts a differential update mechanism (bsdiff) allowing for extremely small application updates, sometimes as low as 4KB. Current stable versions are `v1.x`, with active beta development continuing in the `v1.17.x-beta` series, indicating a frequent release cadence for enhancements and fixes.
Common errors
-
error: bun: command not found
cause The Bun runtime is not installed globally or is not accessible in the system's PATH. Electrobun heavily relies on Bun.fixInstall Bun according to its official documentation (`curl -fsSL https://bun.sh/install | bash`) or ensure the `bun` executable is in your system's PATH. -
Cannot find module 'electrobun/bun' or 'electrobun/view' from '...' at '...' error: module not found
cause The application code is attempting to import Electrobun APIs from an incorrect or non-existent path. Electrobun APIs are exposed via specific subpaths for main and renderer processes.fixEnsure main process code imports from `electrobun/bun` (e.g., `import { BrowserWindow } from 'electrobun/bun';`) and renderer process code imports from `electrobun/view` (e.g., `import { ipcRenderer } from 'electrobun/view';`). Verify that `electrobun` is correctly installed in `node_modules` (or `bun_modules`). -
electrobun: command not found
cause The `electrobun` CLI executable is not found in the system's PATH. This can happen if it's installed locally but not invoked via `bunx` or `npx`.fixWhen using `electrobun` CLI commands (like `electrobun init`, `electrobun dev`, `electrobun build`), prefix them with `bunx` (e.g., `bunx electrobun init`) if `electrobun` is only a local dependency. Alternatively, ensure the `node_modules/.bin` directory is in your PATH, or install `electrobun` globally if preferred (though `bunx` is generally recommended for local CLI tools).
Warnings
- breaking Electrobun is under active and rapid development, evidenced by frequent beta releases (e.g., `v1.17.3-beta.X`). While `v1` has launched as stable, minor versions within `v1.x` and beta versions are subject to API changes and potential breaking shifts. Developers should monitor release notes closely.
- gotcha Electrobun leverages native system WebViews (WebKit on macOS, WebView2 on Windows, WebKitGTK on Linux) for rendering. This provides smaller bundle sizes but means UI rendering behavior can exhibit subtle differences across operating systems. Cross-platform testing is crucial for UI consistency.
- gotcha Electrobun deeply relies on the Bun JavaScript runtime, which itself is rapidly evolving. While Bun offers significant performance benefits, its ecosystem is younger than Node.js, and stability for certain edge cases or platform interactions may still require long-term validation.
- gotcha Electrobun's API is split into specific subpaths: `electrobun/bun` for the main process (Bun runtime) and `electrobun/view` for the renderer process (webview context). Attempting to import APIs directly from the top-level `electrobun` package or using incorrect subpaths will result in module not found errors or undefined symbols.
Install
-
npm install electrobun -
yarn add electrobun -
pnpm add electrobun
Imports
- BrowserWindow
import { BrowserWindow } from 'electrobun';import { BrowserWindow } from 'electrobun/bun'; - app
import { app } from 'electrobun/electron-bridge';import { app } from 'electrobun/bun'; - ipcRenderer
import { ipcRenderer } from 'electrobun';import { ipcRenderer } from 'electrobun/view'; - Electrobun (default import)
const Electrobun = require('electrobun/bun');import Electrobun from 'electrobun/bun';
Quickstart
bunx electrobun init my-electrobun-app
cd my-electrobun-app
bun install
// src/main.ts (main Bun process)
import { BrowserWindow, app } from 'electrobun/bun';
import { join } from 'path';
app.on('ready', () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: join(app.getAppPath(), 'renderer', 'preload.ts'),
// sandbox: true, // Enable for untrusted content
},
title: 'Hello Electrobun App',
url: 'views://main/index.html' // or a remote URL like 'https://electrobun.dev'
});
// For development, open DevTools.
// mainWindow.webContents.openDevTools();
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
// src/renderer/preload.ts (preload script for webview context)
import { ipcRenderer } from 'electrobun/view';
// Expose ipcRenderer functions to the window object for the renderer process
window.electrobun = {
sendMessage: (channel: string, data: any) => ipcRenderer.send(channel, data),
onMessage: (channel: string, callback: (...args: any[]) => void) => ipcRenderer.on(channel, callback),
invoke: (channel: string, ...args: any[]) => ipcRenderer.invoke(channel, ...args)
};
// Extend Window interface globally for TypeScript to recognize window.electrobun
declare global {
interface Window {
electrobun: {
sendMessage: (channel: string, data: any) => void;
onMessage: (channel: string, callback: (...args: any[]) => void) => void;
invoke: (channel: string, ...args: any[]) => Promise<any>;
};
}
}
// package.json (add scripts)
// ...
// "scripts": {
// "dev": "electrobun dev",
// "start": "bun run dev",
// "build": "electrobun build"
// },
// ...
bun run dev