Electrobun Deployment
Build ultra-lightweight desktop apps using Electrobun’s Bun backend and system WebView.
Table of Contents
- Overview
- Prerequisites
- Database Options
- Build
- Generated Structure
- Development
- Electrobun’s Typed RPC
- Using Electrobun APIs in Stimulus
- Custom RPC Handlers
- Runtime Detection
- Build for Distribution
- Configuration
- Comparison with Electron and Tauri
- Troubleshooting
- Resources
Overview
Electrobun creates native desktop applications with the smallest bundle sizes of any desktop framework. It uses your system’s WebView for rendering and Bun (TypeScript) for the backend — no Rust required.
Comparison with other desktop targets:
| Aspect | Electron | Tauri | Electrobun |
|---|---|---|---|
| Bundle size | ~150MB | ~3-10MB | ~14MB |
| Startup time | 2-5s | ~500ms | <50ms |
| Update size | 100MB+ | ~10MB | ~14KB |
| Memory usage | Higher | Lower | Lowest |
| Backend | Node.js (JavaScript) | Rust | Bun (TypeScript) |
| WebView | Bundled Chromium | System WebView | System WebView |
Use cases:
- Desktop apps where startup time and update size matter
- Projects where you prefer TypeScript over Rust for native features
- Apps that benefit from Bun’s fast runtime
- Cross-platform distribution (macOS, Windows, Linux)
Platform support: macOS 14+, Windows 11+, Ubuntu 22.04+
Prerequisites
-
Bun runtime — Required for Electrobun backend
curl -fsSL https://bun.sh/install | bash -
Electrobun CLI — Build and development tools
bun add -g electrobun
Database Options
Since Electrobun uses a system WebView (browser-like environment), compatible databases are:
| Adapter | Storage | Notes |
|---|---|---|
sqljs |
SQLite/WASM | Recommended for offline apps |
pglite |
PostgreSQL/WASM | Full PostgreSQL in-browser |
neon |
Serverless PostgreSQL | Requires network |
turso |
SQLite edge | Requires network |
For offline apps, use sqljs which stores data in IndexedDB.
Build
# Build for Electrobun
bin/juntos build -t electrobun -d sqljs
# Navigate to dist
cd dist
Generated Structure
After building, you’ll have:
dist/
├── app/ # Transpiled Rails app
├── lib/ # Runtime
├── index.html # WebView entry point
└── electrobun.config.ts # Electrobun configuration
Development
Run the development server:
bunx --bun vite
Vite works out of the box with Bun — the existing Juntos Vite pipeline works unchanged.
Electrobun’s Typed RPC
Unlike Electron’s channel-based IPC or Tauri’s Rust commands, Electrobun uses a typed RPC model. You define a shared TypeScript type that both sides reference:
// Shared RPC type
type AppRPC = {
bun: {
requests: { readFile: (args: {path: string}) => string };
messages: { logToBun: (args: {msg: string}) => void };
};
webview: {
requests: { getFormData: () => object };
messages: { showNotification: (args: {title: string}) => void };
};
};
The Juntos runtime sets up a default RPC schema. Override Application.defineRPC() to add custom commands.
Using Electrobun APIs in Stimulus
Access Electrobun APIs from your Ruby controllers:
# app/javascript/controllers/desktop_controller.rb
class DesktopController < Stimulus::Controller
def connect
return unless Application.isElectrobun
# Listen for events bridged from Bun process
document.addEventListener("electrobun:quick-capture") do
activateCamera()
end
end
def openFile
# Invoke a Bun-side function (async)
Application.invoke("openFileDialog", {}).then do |path|
console.log("Selected:", path)
end
end
def logMessage(msg)
# Fire-and-forget message to Bun process
Application.send("logToBun", { msg: msg })
end
end
Custom RPC Handlers
To add custom Bun-side commands, extend the Application class:
# app/javascript/application.rb
class Application < Application
def self.defineRPC(electroview)
electroview.defineRPC(
handlers: {
requests: {
readFile: ->(args) { Bun.file(args.path).text() }
},
messages: {
logToBun: ->(args) { console.log(args.msg) }
}
}
)
end
end
Runtime Detection
Electrobun injects window.__electrobunWindowId into every webview automatically. The runtime detects this:
if Application.isElectrobun
# Electrobun-specific code
end
Build for Distribution
# From the dist directory
electrobun build
Electrobun uses bsdiff-based updates, producing patches as small as ~14KB for incremental updates.
Configuration
The generated electrobun.config.ts includes sensible defaults:
export default {
name: "My App",
identifier: "com.example.myapp",
mainEntry: "bun/index.ts",
views: {
"main-ui": {
entry: "index.html"
}
},
window: {
width: 1200,
height: 800,
title: "My App"
}
};
See Electrobun Configuration for all options.
Comparison with Electron and Tauri
| Feature | Electron | Tauri | Electrobun |
|---|---|---|---|
| Generated files | main.js, preload.js |
tauri.conf.json |
electrobun.config.ts |
| Native code | JavaScript (Node.js) | Rust | TypeScript (Bun) |
| IPC model | Channel strings | Command names | Typed RPC |
| Ruby2JS generates | All JavaScript | Frontend only | Frontend only |
| Custom native features | Edit generated JS | Write Rust | Write TypeScript |
| Learning curve | Lower (JS everywhere) | Higher (requires Rust) | Low (TypeScript) |
Choose Electron if you want Ruby2JS to generate everything. Choose Tauri if bundle size matters and you know Rust. Choose Electrobun if you want the smallest bundles with a TypeScript backend.
Troubleshooting
Bun not found
Install Bun:
curl -fsSL https://bun.sh/install | bash
WebView not rendering
Verify your system meets the minimum requirements:
- macOS 14+ (Sonoma or later)
- Windows 11+
- Ubuntu 22.04+
RPC not connecting
Ensure Electroview is initialized before making RPC calls. The Juntos runtime handles this in Application.start(), but custom initialization may need to await it:
Application.start().then do
# Safe to use RPC here
Application.invoke("myCommand", {})
end