Skip to main content
On this page

Dialogs

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.

The familiar browser globals prompt(), alert(), and confirm() work inside deno desktop apps, but instead of reading from the terminal, they show native popup dialogs.

This makes desktop apps feel native without any platform-specific code, and keeps the same API you would write for a browser-side script.

alert(message) Jump to heading

Shows a modal dialog with an OK button. Returns void.

alert("Save complete.");

The current window is the parent: clicking outside the dialog does not dismiss it; the user must click OK.

confirm(message) Jump to heading

Shows a modal dialog with OK and Cancel. Returns boolean: true for OK, false for Cancel.

if (confirm("Discard unsaved changes?")) {
  await closeDocument();
}

prompt(message, defaultValue?) Jump to heading

Shows a modal dialog with a text input plus OK and Cancel. Returns the entered string, or null if the user cancelled.

const name = prompt("New document name:", "Untitled");
if (name !== null) {
  await createDocument(name);
}

When they fire Jump to heading

These functions block the calling code (synchronously) until the user responds. They run on the Deno runtime thread, not the webview, so they do not freeze the rendered UI, but they do pause your handler.

win.addEventListener("menuclick", (e) => {
  if (e.detail.id === "delete") {
    if (confirm("Really delete?")) {
      // … do the deletion
    }
  }
});

If you call them from the webview side (via JavaScript inside the rendered page), the webview's own native dialogs are used instead: window.alert(), window.confirm(), and window.prompt() as the browser implements them. The behavior is similar: a native modal scoped to that webview.

Differences from terminal Deno Jump to heading

In a normal deno run script, these functions read from / write to the terminal: prompt reads a line of stdin, confirm accepts y / n. That terminal behavior would be invisible inside a desktop app, so deno desktop swaps them out for native dialogs without any code change on your part.

File and folder dialogs Jump to heading

Native file-picker and folder-picker dialogs are not yet exposed as a first-class API. Until they are, two workarounds exist:

  1. Use the webview's <input type="file">. The webview shows the OS-native picker, and the resulting File object can be sent over a binding for the Deno side to handle:

    <input id="f" type="file" accept=".json">
    <script>
      document.getElementById("f").addEventListener("change", async (e) => {
        const file = e.target.files[0];
        await bindings.handleFile(file.name, await file.arrayBuffer());
      });
    </script>
    
    win.bind("handleFile", async (name, bytes) => {
      await Deno.writeFile(name + ".bak", new Uint8Array(bytes));
    });
    
  2. Drag-and-drop into the webview. Drop a file onto a <div>, read it with the File API, and pass the bytes through a binding.

A native file-picker API is on the roadmap.

Notifications Jump to heading

System notifications have a dedicated API: the standard Web Notification constructor, callable from your Deno-side code. See Notifications.

Clipboard Jump to heading

A dedicated clipboard API is not yet exposed. Use the Web Clipboard API (navigator.clipboard.readText(), writeText()) from the webview side for now.

Last updated on

Did you find what you needed?

Edit this page
Privacy policy