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
| Capability | Zig API | JavaScript command | Bridge permission | Current native support |
|---|---|---|---|---|
| Open URL in system browser | runtime.openExternalUrl(url) | zero-native.os.openUrl | network | macOS, Linux, and Windows system WebView; macOS Chromium |
| System notification | runtime.showNotification(options) | zero-native.os.showNotification | notifications | macOS, Linux, and Windows system WebView; macOS Chromium |
| Native dialogs | runtime.showOpenDialog(...) / showSaveDialog(...) / showMessageDialog(...) | zero-native.dialog.openFile / saveFile / showMessage | dialog | macOS system WebView and Chromium; Linux and Windows system WebView |
| Reveal path in file manager | runtime.revealPath(path) | zero-native.os.revealPath | filesystem | macOS, Linux, and Windows system WebView; macOS Chromium |
| Recent documents | runtime.addRecentDocument(path) / runtime.clearRecentDocuments() | zero-native.os.addRecentDocument / zero-native.os.clearRecentDocuments | filesystem | macOS, Linux, and Windows system WebView; macOS Chromium |
| Clipboard | runtime.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.write | clipboard | text/plain on supported clipboard hosts; text/html and RTF on macOS system WebView, macOS Chromium, Linux system WebView, and Windows system WebView |
| File drops | Event.files_dropped | window.zero.on("drop:files") | None. Host-emitted event. | macOS, Linux, and Windows system WebView |
| Credential store | runtime.setCredential(options) / runtime.getCredential(key) / runtime.deleteCredential(key) | zero-native.credentials.set / zero-native.credentials.get / zero-native.credentials.delete | credentials | macOS system WebView and macOS Chromium through Keychain; Linux system WebView through Secret Service/libsecret when available; Windows system WebView through Credential Manager |
| App activation events | LifecycleEvent.activate / LifecycleEvent.deactivate | window.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 schemes | Manifest.file_associations / Manifest.url_schemes | None. 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.