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, },});import { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({ title: "My app", url: "views://mainview/index.html", frame: { width: 960, height: 640, },});const window_id = try core.createWindow(.{ .title = "My app", .frame = .{ .x = 160, .y = 100, .width = 960, .height = 640 }, .callbacks = .{ .resize = onResize, .should_close = onShouldClose },});
const webview_id = try core.createWebview(.{ .window_id = window_id, .url = "views://mainview/index.html", .frame = .{ .x = 0, .y = 0, .width = 960, .height = 640 }, .callbacks = .{ .decide_navigation = electrobun.allowAllNavigation },});let mut window_options = WindowOptions::new("My app", Rect::new(160.0, 100.0, 960.0, 640.0));window_options.callbacks = WindowCallbacks { close: Some(main_window_closed), ..WindowCallbacks::default()};let window_id = core.create_window(window_options)?;
let webview_options = WebviewOptions::new( window_id, "views://mainview/index.html", Rect::new(0.0, 0.0, 960.0, 640.0),);let webview_id = core.create_webview(webview_options)?;windowOptions := electrobun.NewWindowOptions( "My app", electrobun.NewRect(160, 100, 960, 640),)windowOptions.Callbacks = electrobun.WindowCallbacks{ Close: func(uint32) { _ = core.StopEventLoop() },}windowID, err := core.CreateWindow(windowOptions)
webviewOptions := electrobun.NewWebviewOptions( windowID, "views://mainview/index.html", electrobun.NewRect(0, 0, 960, 640),)webviewID, err := core.CreateWebview(webviewOptions)window_options := electrobun.defaultWindowOptions("My app")window_options.frame = {x = 160, y = 100, width = 960, height = 640}window_id, window_err := electrobun.createWindow(core, window_options)
webview_options := electrobun.defaultWebviewOptions(window_id)webview_options.url = "views://mainview/index.html"webview_options.frame = {x = 0, y = 0, width = 960, height = 640}webview_id, webview_err := electrobun.createWebview(core, webview_options)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.
| 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. |
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.
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 thewebviewproperty. - Metadata and events:
setTitle,on,ptr, and staticgetById.
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:
| 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.