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.

Constructor options

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.

OptionTypeDefaultPurpose
titlestring"New Window"Native window title.
frame{ x?: number; y?: number; width: number; height: number }800 x 600, centeredInitial position and size.
urlstring | nullnullURL loaded by the initial webview. Use views:// for bundled content.
htmlstring | nullnullHTML string loaded instead of url.
preloadstring | nullnullInline JavaScript or a bundled views:// script URL.
viewsRootstring | nullnullOverride for the bundled views root.
renderer"native" | "cef"Platform build defaultRenderer for the initial webview.
rpcRPC instancenoneMain-process side of the webview RPC transport.
titleBarStyle"default" | "hidden" | "hiddenInset""default"Native title-bar treatment.
styleMaskobjectplatform defaultsAdvanced native style-mask overrides.
transparentbooleanfalseMake the native window background transparent.
passthroughbooleanfalsePass pointer input through transparent regions.
spellCheckbooleanfalseEnable native spell checking where supported.
hiddenbooleanfalseCreate without showing the window.
activatebooleantrueActivate the window when it is created.
trafficLightOffset{ x: number; y: number }{ x: 0, y: 0 }macOS traffic-light offset.
navigationRulesstring | nullnullSerialized navigation policy for the initial webview.
sandboxbooleanfalseDisable 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.

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;

Window lifecycle

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().

Title, position, and size

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;

Webview access

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.

Events and lookup

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.

Public methods

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.

Native SDKs

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:

TypeScriptZig / OdinRustGo
win.setTitle(t)setWindowTitle(id, t)set_window_title(id, t)SetWindowTitle(id, t)
win.show() / hide() / isVisible()showWindow(id, activate) / hideWindow / isWindowVisibleshow_window / hide_window / is_window_visibleShowWindow / HideWindow / IsWindowVisible
win.minimize()isMaximized()minimizeWindow / restoreWindow / maximizeWindow / unmaximizeWindow + is...snake_case equivalentsCamelCase equivalents
win.setFullScreen(b) / setAlwaysOnTop(b) / setVisibleOnAllWorkspaces(b)setWindowFullScreen etc.set_window_full_screen etc.SetWindowFullScreen etc.
win.setPosition / setSize / setFrame / getFrame / centersetWindowPosition / setWindowSize / setWindowFrame / getWindowFrame / centerWindowsnake_caseCamelCase
win.setWindowButtonPosition / get...same names (core-level)snake_caseCamelCase
win.close() / requestClose()closeWindow / requestWindowCloseclose_window / request_window_closeCloseWindow / 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.