Capabilities

zero-native capabilities are native OS services and app events exposed through PlatformServices, runtime methods, lifecycle events, and guarded bridge commands. Web content does not receive capability access by default.

Current capability pack

CapabilityZig APIJavaScript commandBridge permissionCurrent native support
Open URL in system browserruntime.openExternalUrl(url)zero-native.os.openUrlnetworkmacOS, Linux, and Windows system WebView; macOS Chromium
System notificationruntime.showNotification(options)zero-native.os.showNotificationnotificationsmacOS, Linux, and Windows system WebView; macOS Chromium
Native dialogsruntime.showOpenDialog(...) / showSaveDialog(...) / showMessageDialog(...)zero-native.dialog.openFile / saveFile / showMessagedialogmacOS system WebView and Chromium; Linux and Windows system WebView
Reveal path in file managerruntime.revealPath(path)zero-native.os.revealPathfilesystemmacOS, Linux, and Windows system WebView; macOS Chromium
Recent documentsruntime.addRecentDocument(path) / runtime.clearRecentDocuments()zero-native.os.addRecentDocument / zero-native.os.clearRecentDocumentsfilesystemmacOS, Linux, and Windows system WebView; macOS Chromium
Clipboardruntime.readClipboard() / runtime.writeClipboard(text) / runtime.readClipboardData(mimeType) / runtime.writeClipboardData(data)zero-native.clipboard.readText / zero-native.clipboard.writeText / zero-native.clipboard.read / zero-native.clipboard.writeclipboardtext/plain on supported clipboard hosts; text/html and RTF on macOS system WebView, macOS Chromium, Linux system WebView, and Windows system WebView
File dropsEvent.files_droppedwindow.zero.on("drop:files")None. Host-emitted event.macOS, Linux, and Windows system WebView
Credential storeruntime.setCredential(options) / runtime.getCredential(key) / runtime.deleteCredential(key)zero-native.credentials.set / zero-native.credentials.get / zero-native.credentials.deletecredentialsmacOS system WebView and macOS Chromium through Keychain; Linux system WebView through Secret Service/libsecret when available; Windows system WebView through Credential Manager
App activation eventsLifecycleEvent.activate / LifecycleEvent.deactivatewindow.zero.on("app:activate") / window.zero.on("app:deactivate")None. Host-emitted event.macOS, Linux, and Windows system WebView; macOS Chromium
File associations and URL schemesManifest.file_associations / Manifest.url_schemesNone. Packaging metadata.None. Manifest-only declaration.Parsed, validated, and emitted in macOS, Linux, and Windows package registration metadata.

Unsupported platform hosts reject with the standard unsupported-service error.

Support discovery

Use runtime.supports(...) before native code shows optional affordances. Trusted WebView code can make the same check with zero-native.platform.supports when that built-in command is explicitly allowed:

const support = {
  notifications: await window.zero.platform.supports("notifications"),
  dialogs: await window.zero.platform.supports("dialogs"),
  clipboardRichData: await window.zero.platform.supports("clipboard_rich_data"),
  credentials: await window.zero.platform.supports("credentials"),
  fileDrops: await window.zero.platform.supports("file_drops"),
};

Security

OS bridge commands are default-deny. Add explicit builtin_bridge entries for each command your app calls:

.builtin_bridge = .{
    .enabled = true,
    .commands = &.{
        .{ .name = "zero-native.platform.supports", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.os.openUrl", .permissions = .{ "network" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.os.showNotification", .permissions = .{ "notifications" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.dialog.openFile", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.dialog.saveFile", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.dialog.showMessage", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.os.revealPath", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.os.addRecentDocument", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.os.clearRecentDocuments", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.clipboard.readText", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.clipboard.writeText", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.clipboard.read", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.clipboard.write", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.credentials.set", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.credentials.get", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
        .{ .name = "zero-native.credentials.delete", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
    },
},

Opening external URLs is also gated by the external-link policy:

.security = .{
    .navigation = .{
        .external_links = .{
            .action = .open_system_browser,
            .allowed_urls = &.{ "https://example.com/docs/*" },
        },
    },
},

JavaScript

await window.zero.os.openUrl("https://example.com/docs/start");
await window.zero.os.showNotification({
  title: "Build finished",
  subtitle: "zero-native",
  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 zero-native");
const text = await window.zero.clipboard.readText();
await window.zero.clipboard.write({
  mimeType: "text/html",
  data: "<strong>Copied from zero-native</strong>",
});
const html = await window.zero.clipboard.read({ mimeType: "text/html" });

window.zero.on("drop:files", (event) => {
  console.log(event.paths);
});

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",
});

window.zero.on("app:activate", () => {
  refreshForegroundState();
});

See also: Builtin Commands and Security.