Builtin Commands
The Native SDK provides built-in bridge commands for app command routing, window management, generic native views, layered WebViews, platform support queries, native dialogs, selected OS capabilities, and credential storage. These are controlled by the builtin_bridge policy in RuntimeOptions, separate from app-defined bridge handlers.
Command Routing
| Command | Required permission | Description |
|---|---|---|
native-sdk.command.invoke | command | Dispatch an Event.command into the app runtime from the calling WebView |
native-sdk.command.list | command | List the manifest command catalog loaded into the runtime |
Command routing is available through window.zero.commands.invoke(...) when js_window_api is true. The manifest command catalog is available through window.zero.commands.list(). When runtime permissions are configured, command helpers require the command permission; the legacy window permission is still accepted for compatibility. The runtime emits a CommandEvent with source = .bridge, the calling window_id, and the calling view label when the request comes from a named child WebView.
Native controls can also bind a command when created with runtime.createView(...) or window.zero.views.create(...). On macOS, Linux, and Windows system WebView builds, native button-style controls dispatch the command with the native window_id and the originating view label. Controls inside a toolbar report source = .toolbar; other native controls report source = .native_view.
Platform Support Commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.platform.supports | window | Return whether the current platform and web engine support a feature |
Platform support queries are available through window.zero.platform.supports(...) when js_window_api is true. The command accepts feature names from PlatformFeature, including main_webview, child_webviews, native_views, native_control_commands, menus, tray, shortcuts, dialogs, clipboard_text, clipboard_rich_data, open_url, reveal_path, notifications, recent_documents, credentials, file_drops, app_activation_events, and gpu_surfaces. JavaScript callers can also use camelCase aliases such as mainWebView, nativeControlCommands, clipboardRichData, recentDocuments, fileDrops, appActivationEvents, and gpuSurfaces. The helper accepts either a string or a selector object with feature or name; raw bridge payloads may use the same fields. Use an explicit builtin_bridge policy when you want per-command origin lists.
Window commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.window.list | window | List all open windows |
native-sdk.window.create | window | Create a new window |
native-sdk.window.focus | window | Focus a window by ID |
native-sdk.window.close | window | Close a window by ID |
Window commands are available through window.zero.windows.* when js_window_api is true, but the runtime still checks the request origin and the window permission when permissions are configured. Use an explicit builtin_bridge policy when you want per-command origin lists.
View Commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.view.create | view | Create a generic native view or WebView-backed view in the calling window |
native-sdk.view.list | view | List generic views and WebViews in the calling window |
native-sdk.view.update | view | Patch frame, layer, visibility, enabled state, role, text, command, or WebView URL |
native-sdk.view.setFrame | view | Move or resize a view |
native-sdk.view.setVisible | view | Show or hide a view |
native-sdk.view.focus | view | Focus a view when the backend supports native focus for that kind |
native-sdk.view.focusNext / native-sdk.view.focusPrevious | view | Move focus through visible, enabled native controls and WebView-backed views |
native-sdk.view.close | view | Close a generic view or child WebView |
View commands are available through window.zero.views.* when js_window_api is true. They use origin checks and the view permission when runtime permissions are configured; the legacy window permission is still accepted for compatibility. windowId must match the calling window when provided. The update(label, patch), focus(label), and close(label) helpers accept string labels for the calling window; pass selector objects when you need an explicit windowId. View responses include frame, layer, visibility, enabled, focus, role, accessibility label, text, command, cursor, and open state. GPU responses also include surface presentation fields, input latency budget fields, retained canvas frame counters, and retained widget counters. kind: "webview" routes through the WebView backend. The macOS, Linux, and Windows system-WebView backends support native toolbar, titlebar_accessory, sidebar, statusbar, split, stack, button, icon_button, list_item, checkbox, toggle, segmented_control, text_field, search_field, label, spacer, and progress_indicator views. The macOS system-WebView backend also supports gpu_surface; Chromium hosts and unsupported native kinds return explicit unsupported-backend errors until implemented.
WebView Commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.webview.create | window | Create a named WebView in a window |
native-sdk.webview.list | window | List WebViews in the calling window |
native-sdk.webview.setFrame | window | Move or resize a WebView |
native-sdk.webview.navigate | window | Navigate a WebView |
native-sdk.webview.setZoom | window | Set page zoom from 0.25 to 5.0 |
native-sdk.webview.setLayer | window | Change native stack order |
native-sdk.webview.close | window | Close a WebView |
WebView commands are available through window.zero.webviews.* when js_window_api is true. They use the same origin and window permission checks as window commands. WebView URLs are also checked against security.navigation.allowed_origins. Backend-specific gaps reject with invalid_request and an actionable unsupported-backend message.
If windowId is omitted, the runtime uses the window that sent the bridge message. If provided, windowId must match that same calling window. Child WebViews are isolated by default and receive window.zero only when created with bridge: true. The startup WebView is always listed as main; that label is reserved and cannot be used for child WebView creation.
Dialog commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.dialog.openFile | dialog | Show a file open dialog |
native-sdk.dialog.saveFile | dialog | Show a file save dialog |
native-sdk.dialog.showMessage | dialog | Show a message dialog |
Dialog commands are always default-deny and require an explicit builtin_bridge policy.
OS Commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.os.openUrl | network | Open an allowed http:// or https:// URL in the system browser |
native-sdk.os.showNotification | notifications | Show a native system notification with a title, optional subtitle, and optional body |
native-sdk.os.revealPath | filesystem | Reveal a local file or folder path in the platform file manager |
native-sdk.os.addRecentDocument | filesystem | Add a local path to the platform recent documents list |
native-sdk.os.clearRecentDocuments | filesystem | Clear recent documents registered by the application where the platform supports it |
OS commands are always default-deny and require an explicit builtin_bridge policy. native-sdk.os.openUrl also checks security.navigation.external_links; the URL must match the external link allowlist before the platform service is called. macOS, Linux, and Windows system WebView hosts implement openUrl, revealPath, notifications, and recent-document commands; macOS Chromium also implements the current OS command set. Other platform hosts return invalid_request with the standard unsupported-service message until implemented.
Credential Commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.credentials.set | credentials | Store a secret by service and account |
native-sdk.credentials.get | credentials | Read a secret by service and account, returning null when it is missing |
native-sdk.credentials.delete | credentials | Delete a stored secret by service and account |
Credential commands are always default-deny and require an explicit builtin_bridge policy. The macOS system WebView and macOS Chromium hosts store secrets in Keychain. The Linux system WebView host stores secrets through Secret Service/libsecret when available. The Windows system WebView host stores secrets in Credential Manager. Other platform hosts return invalid_request with the standard unsupported-service message until implemented.
Clipboard Commands
| Command | Required permission | Description |
|---|---|---|
native-sdk.clipboard.readText | clipboard | Read text/plain from the system clipboard |
native-sdk.clipboard.writeText | clipboard | Write text/plain to the system clipboard |
native-sdk.clipboard.read | clipboard | Read clipboard data by MIME type and return { mimeType, data } |
native-sdk.clipboard.write | clipboard | Write clipboard data by MIME type |
Clipboard commands are always default-deny and require an explicit builtin_bridge policy. Supported clipboard hosts provide text/plain through the existing text clipboard path. macOS system WebView, macOS Chromium, Linux system WebView, and Windows system WebView also support text/html, text/rtf, and application/rtf.
Enabling builtin commands
const app_permissions = [_][]const u8{
native_sdk.security.permission_command,
native_sdk.security.permission_view,
native_sdk.security.permission_dialog,
native_sdk.security.permission_window,
native_sdk.security.permission_network,
native_sdk.security.permission_filesystem,
native_sdk.security.permission_clipboard,
native_sdk.security.permission_notifications,
native_sdk.security.permission_credentials,
};
.security = .{
.permissions = &app_permissions,
.navigation = .{
.allowed_origins = &.{ "zero://app" },
.external_links = .{
.action = .open_system_browser,
.allowed_urls = &.{ "https://example.com/docs/*" },
},
},
},
.builtin_bridge = .{
.enabled = true,
.commands = &.{
.{ .name = "native-sdk.window.list", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.command.invoke", .permissions = .{ "command" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.command.list", .permissions = .{ "command" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.platform.supports", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.window.create", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.create", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.list", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.update", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.setFrame", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.setVisible", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.focus", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.focusNext", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.focusPrevious", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.view.close", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.create", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.list", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.setFrame", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.navigate", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.setZoom", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.setLayer", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.webview.close", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.dialog.openFile", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.dialog.saveFile", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.dialog.showMessage", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.os.openUrl", .permissions = .{ "network" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.os.showNotification", .permissions = .{ "notifications" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.os.revealPath", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.os.addRecentDocument", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.os.clearRecentDocuments", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.clipboard.readText", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.clipboard.writeText", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.clipboard.read", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.clipboard.write", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.credentials.set", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.credentials.get", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
.{ .name = "native-sdk.credentials.delete", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
},
},JavaScript usage
await window.zero.windows.create({
label: "tools",
title: "Tools",
width: 420,
height: 320,
});
const preview = await window.zero.webviews.create({
label: "preview",
url: "https://example.com",
frame: { x: 24, y: 24, width: 480, height: 320 },
layer: 10,
bridge: false,
});
await preview.setZoom(1.25);
await preview.setLayer(20);
await preview.close();
const toolbar = await window.zero.views.create({
label: "toolbar",
kind: "toolbar",
frame: { x: 0, y: 0, width: 720, height: 44 },
role: "toolbar",
});
await window.zero.views.create({
label: "refresh",
kind: "button",
parent: "toolbar",
frame: { x: 12, y: 8, width: 96, height: 28 },
accessibilityLabel: "Refresh workspace",
text: "Refresh",
command: "app.refresh",
});
await toolbar.setVisible(false);
await window.zero.commands.invoke("app.save");
const commands = await window.zero.commands.list();
const hasNativeViews = await window.zero.platform.supports("native_views");
const files = await window.zero.invoke("native-sdk.dialog.openFile", {
title: "Select a file",
allowMultiple: true,
});
const result = await window.zero.invoke("native-sdk.dialog.showMessage", {
style: "warning",
title: "Confirm",
message: "Are you sure?",
primaryButton: "Yes",
secondaryButton: "No",
});
await window.zero.os.openUrl("https://example.com/docs/start");
await window.zero.os.showNotification({
title: "Build finished",
subtitle: "native-sdk",
body: "All checks passed.",
});
await window.zero.os.revealPath("/Users/me/Downloads/report.pdf");
await window.zero.os.addRecentDocument("/Users/me/Downloads/report.pdf");
await window.zero.os.clearRecentDocuments();
await window.zero.clipboard.writeText("Copied from Native SDK");
const text = await window.zero.clipboard.readText();
await window.zero.clipboard.write({
mimeType: "text/html",
data: "<strong>Copied from Native SDK</strong>",
});
const html = await window.zero.clipboard.read({ mimeType: "text/html" });
await window.zero.credentials.set({
service: "com.example.app",
account: "current-user",
secret: "session-token",
});
const token = await window.zero.credentials.get({
service: "com.example.app",
account: "current-user",
});
await window.zero.credentials.delete({
service: "com.example.app",
account: "current-user",
});See also: Multiple WebViews for frame and layer semantics, Dialogs for the full dialog type reference, Capabilities for OS capability support, and Security for policy details.