On this page
Dialogs
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:
-
Use the webview's
<input type="file">. The webview shows the OS-native picker, and the resultingFileobject 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)); }); -
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.