On this page
Notifications
deno desktop ships in Deno v2.9.0 and is not in a stable release yet. To try
it now, run deno upgrade canary to install the
canary build. The command, configuration
keys, and TypeScript APIs may still change before the feature is stable.
deno desktop implements the standard
Web Notifications API.
The same Notification constructor you would use in a browser shows a native
OS notification (macOS User Notifications, Windows toast notifications, or the
Linux desktop notification service) from your Deno-side code.
const n = new Notification("Build complete", {
body: "Your binary is ready.",
});
n.addEventListener("click", () => win.focus()); // bring the app to front
Notification is only defined in apps compiled with deno desktop. In a plain
deno run script it does not exist.
Permissions Jump to heading
Notifications are gated by an OS-level permission, exactly as on the web. Check
the current state with Notification.permission and request it with
Notification.requestPermission():
if (Notification.permission !== "granted") {
const permission = await Notification.requestPermission();
if (permission !== "granted") {
// The user declined, don't try to notify.
return;
}
}
new Notification("All set", { body: "Notifications are enabled." });
Notification.permission is a cached synchronous getter holding the result
of the most recent query or request. requestPermission() triggers a system
prompt the first time the user has not yet decided, and resolves to "granted",
"denied", or "default".
For the live OS state, including whether the platform has a permission model at all, query the Permissions API:
const status = await navigator.permissions.query({ name: "notifications" });
console.log(status.state); // "granted" | "denied" | "prompt"
On a platform or backend with no permission concept (an unbundled macOS process,
some Linux notification daemons), the query reports "prompt" and notifications
are shown without an explicit grant.
macOS only hands out notification permission to an app with a stable code
identity. deno desktop ad-hoc-signs every bundle it produces (and re-signs the
cached runtime in --hmr mode) so this works out of the box. See
Distribution for configuring a
real signing identity.
Options Jump to heading
The constructor takes the standard NotificationOptions:
new Notification("New message", {
body: "Alice: are we still on for 3pm?",
icon: "data:image/png;base64,iVBORw0KGgo…",
tag: "chat-alice",
requireInteraction: true,
silent: false,
});
| Option | Type | Notes |
|---|---|---|
body |
string |
The notification's body text. |
icon |
string |
Icon URL. Only data: URLs are shown (see below). |
tag |
string |
Replaces any existing notification with the same tag instead of stacking. |
requireInteraction |
boolean |
Keep the notification visible until the user dismisses it. |
silent |
boolean | null |
Suppress the notification sound. |
badge |
string |
Badge URL (platform-dependent). |
dir |
"auto" | "ltr" | "rtl" |
Text direction. |
lang |
string |
BCP 47 language tag. |
data |
any |
Arbitrary data attached to the notification; read it back from data. |
Icons Jump to heading
The Web Notifications spec types icon as a URL string. The desktop runtime can
only resolve data: URLs synchronously, so an inline data:image/png;base64,…
icon is rendered. Other URL schemes (https:, file:) are accepted and
round-trip through the icon property, but the OS notification is shown without
an icon. To use a file on disk, read it and encode it as a data: URL:
const bytes = await Deno.readFile("./icons/alert.png");
const dataUrl = "data:image/png;base64," + encodeBase64(bytes);
new Notification("Heads up", { icon: dataUrl });
Events Jump to heading
A Notification is an EventTarget. Listen with addEventListener or the
on<event> properties:
const n = new Notification("Download finished");
n.onshow = () => console.log("shown");
n.onclick = () => openDownloadsFolder();
n.onclose = () => console.log("dismissed");
n.onerror = () => console.warn("the OS rejected the notification");
| Event | When it fires |
|---|---|
show |
The OS displayed the notification. |
click |
The user clicked the notification body. |
close |
The user dismissed it, or it expired. |
error |
The OS could not display it (e.g. permission denied). |
Dismissing Jump to heading
Call close() to dismiss a notification programmatically:
const n = new Notification("Connecting…");
// later, once connected:
n.close();
Notifications are otherwise fire-and-forget. The OS owns them once shown, and
close() is a best-effort request.