Skip to main content
On this page

Notifications

Coming in Deno 2.9

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 requires a code-signed bundle

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.

Last updated on

Did you find what you needed?

Edit this page
Privacy policy