Skip to content

BrowserWindow

Every runtime creates native windows through the same core. In TypeScript (Cottontail/Bun), BrowserWindow creates a window and its initial BrowserView; the native SDKs create windows and webviews as two explicit calls.

import { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({
title: "My app",
url: "views://mainview/index.html",
frame: {
width: 960,
height: 640,
},
});

In TypeScript, omitting frame.x or frame.y centers the window, the instance is available immediately, and win.webview is the BrowserView created for its content. Native window/webview creation and its required lifecycle setup (core loading, the blocking main thread, the webview runtime) are covered end to end in the per-runtime Hello World walkthroughs.

The rest of this page documents the TypeScript class. Every window operation below also exists in the native SDKs as a Core call keyed by window id — see the mapping at the end of the page.

All options are optional because the constructor accepts Partial<WindowOptionsType>. The table describes the defaults used when an options object is supplied. For compatibility, calling new BrowserWindow() with no argument uses the legacy starter window: title "Electrobun", size 800 by 600, and URL https://electrobun.dev.

Option Type Default Purpose
title string "New Window" Native window title.
frame { x?: number; y?: number; width: number; height: number } 800 x 600, centered Initial position and size.
url string | null null URL loaded by the initial webview. Use views:// for bundled content.
html string | null null HTML string loaded instead of url.
preload string | null null Inline JavaScript or a bundled views:// script URL.
viewsRoot string | null null Override for the bundled views root.
allowedProtocols { views?: boolean; appData?: boolean } { views: true, appData: false } Grant the initial webview access to Electrobun’s filesystem-backed URL schemes.
renderer "native" | "cef" Platform build default Renderer for the initial webview.
rpc RPC instance none Main-process side of the webview RPC transport.
titleBarStyle "default" | "hidden" | "hiddenInset" "default" Native title-bar treatment.
styleMask object platform defaults Advanced native style-mask overrides.
transparent boolean false Make the native window background transparent.
passthrough boolean false Pass pointer input through transparent regions.
spellCheck boolean false Enable native spell checking where supported.
hidden boolean false Create without showing the window.
activate boolean true Activate the window when it is created.
trafficLightOffset { x: number; y: number } { x: 0, y: 0 } macOS traffic-light offset.
navigationRules string | null null Serialized navigation policy for the initial webview.
sandbox boolean false Disable RPC for untrusted content; event emission remains available.

Only bundle and select CEF when the app needs it. See Bundling CEF for the build configuration.

allowedProtocols applies to this window’s initial webview. Enable appData only when its content and navigation are trusted; permission persists across navigation. Additional BrowserView instances have their own settings. See Bundled and app-owned assets for examples.

import { BrowserWindow } from "electrobun/main";
const cefWindow = new BrowserWindow({
title: "CEF content",
url: "views://mainview/index.html",
renderer: "cef",
});
const sandboxedWindow = new BrowserWindow({
title: "Untrusted content",
url: "https://example.com",
sandbox: true,
});
void cefWindow;
void sandboxedWindow;
import { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({
title: "Lifecycle",
url: "views://mainview/index.html",
});
win.show();
win.showInactive();
win.hide();
const visible = win.isVisible();
win.activate();
win.minimize();
win.unminimize();
const minimized = win.isMinimized();
win.maximize();
win.unmaximize();
const maximized = win.isMaximized();
win.setFullScreen(true);
const fullScreen = win.isFullScreen();
win.setAlwaysOnTop(true);
const alwaysOnTop = win.isAlwaysOnTop();
win.setVisibleOnAllWorkspaces(true);
const onAllWorkspaces = win.isVisibleOnAllWorkspaces();
win.requestClose(); // Runs the normal close-request path.
win.close(); // Closes the window directly.
void visible;
void minimized;
void maximized;
void fullScreen;
void alwaysOnTop;
void onAllWorkspaces;

focus() remains as a deprecated alias for activate().

import { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({
title: "Geometry",
url: "views://mainview/index.html",
frame: { width: 800, height: 600 },
});
win.setTitle("Updated title");
win.setPosition(120, 80);
win.setSize(1024, 720);
win.setFrame(120, 80, 1024, 720);
win.center();
const frame = win.getFrame();
const position = win.getPosition();
const size = win.getSize();
win.setWindowButtonPosition(14, 14);
const buttonPosition = win.getWindowButtonPosition();
void frame;
void position;
void size;
void buttonPosition;

The initial view is exposed as win.webview. Content, developer tools, find, zoom, and navigation operations belong to BrowserView:

import { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({
title: "Webview access",
url: "views://mainview/index.html",
});
win.webview.loadURL("views://details/index.html");
win.webview.executeJavascript("document.body.dataset.ready = 'true'");
win.webview.openDevTools();
win.webview.findInPage("example", { forward: true, matchCase: false });
win.webview.stopFindInPage();
win.setPageZoom(1.25);
const zoom = win.getPageZoom();
const spellCheckChanged = win.setSpellCheck(true);
void zoom;
void spellCheckChanged;

See BrowserView for the complete view API.

on() scopes an Electrobun window event to this instance. Event payloads are currently typed as unknown, so narrow them before reading application data.

import { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({
title: "Events",
url: "views://mainview/index.html",
});
win.on("resize", (event: unknown) => {
console.log("Window resized", event);
});
const sameWindow = BrowserWindow.getById(win.id);
sameWindow?.activate();
const nativePointer = win.ptr;
void nativePointer;

The native pointer is an advanced FFI escape hatch. Application code should use the class methods unless it is integrating directly with a platform API.

The current public control surface is:

  • Lifecycle: close, requestClose, activate, show, showInactive, hide, isVisible.
  • Window state: minimize, unminimize, isMinimized, maximize, unmaximize, isMaximized, setFullScreen, isFullScreen, setAlwaysOnTop, isAlwaysOnTop, setVisibleOnAllWorkspaces, isVisibleOnAllWorkspaces.
  • Geometry: setPosition, center, setSize, setFrame, getFrame, getPosition, getSize, setWindowButtonPosition, getWindowButtonPosition.
  • Content: setPageZoom, getPageZoom, setSpellCheck, and the webview property.
  • Metadata and events: setTitle, on, ptr, and static getById.

Zig, Rust, Go, and Odin expose the same window operations procedurally on Core, keyed by the u32 window id createWindow returns. The verb set matches the class methods one-to-one; only naming style differs per language:

TypeScript Zig / Odin Rust Go
win.setTitle(t) setWindowTitle(id, t) set_window_title(id, t) SetWindowTitle(id, t)
win.show() / hide() / isVisible() showWindow(id, activate) / hideWindow / isWindowVisible show_window / hide_window / is_window_visible ShowWindow / HideWindow / IsWindowVisible
win.minimize() … isMaximized() minimizeWindow / restoreWindow / maximizeWindow / unmaximizeWindow + is... snake_case equivalents CamelCase equivalents
win.setFullScreen(b) / setAlwaysOnTop(b) / setVisibleOnAllWorkspaces(b) setWindowFullScreen etc. set_window_full_screen etc. SetWindowFullScreen etc.
win.setPosition / setSize / setFrame / getFrame / center setWindowPosition / setWindowSize / setWindowFrame / getWindowFrame / centerWindow snake_case CamelCase
win.setWindowButtonPosition / get... same names (core-level) snake_case CamelCase
win.close() / requestClose() closeWindow / requestWindowClose close_window / request_window_close CloseWindow / RequestWindowClose
win.on("resize", ...) WindowCallbacks passed to createWindow (close, should_close, move, resize, focus, blur, key) WindowCallbacks (same slots) WindowCallbacks (same slots)

Zig and Odin additionally ship an optional WindowRegistry / BrowserWindowRef layer covering getById, close/request-close, frame, center, and button position. Not available natively: setPageZoom / setSpellCheck live on the webview id instead (setWebviewPageZoom, setWebviewSpellCheck), and there is no event emitter — events are the C callbacks registered at creation.