new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Deno · all subjects

cli/desktop

208 notes in this subject, read out of this brain and free to use. This is page 1 of 4.

WebView backend characteristics

The WebView backend uses the operating system's own webview: WKWebView on macOS, WebView2 on Windows, and WebKitGTK on Linux. It results in a smaller app size (just code plus the backend shim), but rendering and feature support vary per platform and OS version. Some web features may be missing or behave differently, such as Web Audio variants and WebGPU availability. DevTools are not available with WebView.

CEF backend features and size

The CEF (Chromium Embedded Framework) backend provides bundled Chromium, the same engine powering Chrome, Electron, and Slack. It offers identical rendering on macOS, Windows, and Linux, full web platform support including modern CSS, ES modules, WebGPU, and WebRTC, and supports all Deno desktop features (DevTools, autoUpdate, tray, dock). The framework alone is approximately 150 MB, making it the largest backend option.

Backend interchangeability between CEF and WebView

CEF and WebView backends are interchangeable for app code (windows, bindings, events, navigation, JS execution) without changes. The `raw` backend is not interchangeable; any APIs that interact with web content (navigation, bindings, `executeJs`, etc.) are unavailable on the `raw` backend.

desktop backend selection in deno.json

The `desktop.backend` field in `deno.json` can be used to select which rendering engine the desktop app embeds instead of using the `--backend` flag.

Raw backend characteristics

The `raw` backend provides no web engine. It offers window management, input events, clipboard, and the native API surface, but no webview, no `Deno.serve()` auto-binding, and no `bindings.<name>()` proxy. The `raw` backend is only selectable through the `desktop.backend` field in `deno.json`; the `--backend` flag does not accept `raw`.

desktop backend selection with --backend flag

The `--backend` flag selects which rendering engine a desktop app embeds. Options are `cef`, `webview`, and `raw`. If no backend is chosen, `deno desktop` uses the WebView backend by default.

Backend selection guidelines

Use `cef` for identical rendering everywhere or for WebGPU and cutting-edge web APIs on all platforms. Use `webview` for the smallest possible binary or for internal macOS apps where you control the OS version. Use `raw` for custom 2D/3D rendering with no HTML.

Backend download and caching

Deno CLI downloads prebuilt backend binaries automatically. Downloads are checksum-verified and cached under `<deno_dir>/`. The first build for a new backend and target downloads the archive (a few hundred megabytes for CEF), and subsequent builds use the cache.

Cross-compilation with desktop backends

The `--target` and `--all-targets` flags work with any backend. The CLI downloads the prebuilt backend archive matching the target triple, with no local engine toolchain needed.

deno desktop comparison with Electron, Electrobun, Tauri, and Dioxus

deno desktop compared to alternatives across dimensions: Language (Electron: JS/TS Node.js, Electrobun: JS/TS Bun, Tauri: Rust + web frontend, Dioxus: Rust, deno desktop: JS/TS Deno); Web engine (Electron: Bundled Chromium, Electrobun: System WebView, Tauri: System WebView, Dioxus: System WebView, deno desktop: Bundled CEF or WebView); Consistent rendering (Electron: Yes, Electrobun: No, Tauri: No, Dioxus: No, deno desktop: Yes with CEF); Process model (Electron: Multi-process, Electrobun: Multi-process, Tauri: Multi-process, Dioxus: Single process, deno desktop: Multi-thread CEF or process group WebView); Backend UI communication (Electron: IPC, Electrobun: IPC, Tauri: IPC, Dioxus: Native Rust, deno desktop: In-process channels); App size (Electron: ~100 MB+, Electrobun: ~61 MB, Tauri: ~2-10 MB, Dioxus: ~5 MB, deno desktop: ~40 MB or ~150 MB with CEF); npm/Node compat (Electron: Yes, Electrobun: Yes, Tauri: No, Dioxus: No, deno desktop: Yes); Framework auto-detect (Electron: No, Electrobun: No, Tauri: No, Dioxus: No, deno desktop: Yes); HMR (Electron: No, Electrobun: Yes, Tauri: Yes Vite-based, Dioxus: Yes dx serve, deno desktop: Yes); Built-in auto-update (Electron: Full binary, Electrobun: bsdiff, Tauri: Plugin, Dioxus: None, deno desktop: bsdiff); Built-in installers (Electron: Yes, Electrobun: No, Tauri: Yes, Dioxus: No, deno desktop: Partial DMG AppImage); Cross-compile (Electron: Yes electron-builder, Electrobun: No needs target OS, Tauri: No needs target OS, Dioxus: No, deno desktop: Yes with --target); macOS/Windows/Linux (all support all three); iOS/Android (Electron: No, Electrobun: No, Tauri: Yes, Dioxus: Yes, deno desktop: Not yet).

When to choose alternative desktop application frameworks

Choose Tauri if binary size is non-negotiable, you do not need npm, and you want mobile support. Choose Electron if team's existing tooling, signing, and CI already target Electron. Choose Dioxus if writing Rust top to bottom. Choose Electrobun if you want to work in the Bun ecosystem.

When to choose deno desktop for desktop applications

Choose deno desktop if: codebase is JavaScript/TypeScript and you do not want to write Rust; you want consistent rendering across platforms and are OK with binary size of bundling Chromium; you already have Next.js/Astro/Fresh web app and want desktop version with no code changes; you want cross-compilation from one machine; you need full Node compatibility (npm packages, native modules) in backend code; you want auto-update built in rather than bolted on.

deno desktop current limitations

deno desktop does not yet support: one-step macOS notarization (code-signing is ad-hoc by default or with Developer ID identity, but notarization requires separate notarytool step); Windows MSI or Linux .deb/.rpm installer outputs; auto-update on Windows (bsdiff auto-update works on macOS and Linux but not Windows); iOS/Android targets; native clipboard and secure-storage APIs (Web Clipboard API available from webview side); native notifications and system tray/dock APIs are available but runtime permissions for desktop apps (permission prompts on filesystem/network access using Deno's permission system for desktop sandboxing) are not yet implemented; shared CEF runtime across apps (each app currently bundles its own CEF copy; shared managed runtime on roadmap would reduce sizes to few MB per app).

deno desktop strengths and features

deno desktop has zero-config framework support: running deno desktop . on Next.js, Astro, or Fresh projects requires no adapter or config, with production server in release mode and dev server under --hmr. It supports cross-compilation from one machine using deno compile --target syntax. It provides full Node compatibility with choice of backend: defaults to OS webview for small size like Tauri, but includes full Node compat layer through Deno including npm: imports in handlers and bindings, with optional Chromium CEF bundling for consistent rendering. Backend and UI communication uses in-process channels instead of IPC, with values encoded as JSON but without cross-process round-trip. It includes built-in auto-update with binary diffs using bsdiff patches, integrated with the runtime with no separate updater binary, automatic rollback, and manifest polling in one API.

output configuration per platform

The `output` field specifies per-platform output paths. On macOS, a `.app` extension produces a macOS application bundle, while `.dmg` produces a DMG disk image built via `hdiutil`. On Windows, no extension or a directory produces an app directory with a `.bat` launcher and DLLs, while `.msi` produces a Windows Installer package. On Linux, no extension or a directory produces an app directory with launcher script, `.AppImage` produces an `.AppImage` single-file bundle, `.deb` produces a Debian/Ubuntu package, and `.rpm` produces a Fedora/RHEL package. The CLI flag `--output` overrides this for one build.

desktop app working directory behavior

The compiled binary runs with the current working directory set to the user's `cwd`, not the directory containing the binary. If the app needs to find files relative to itself (framework build outputs, static assets), use `import.meta` or the framework's own resolution; do not assume `Deno.cwd()`. For framework projects this is handled automatically: detected build outputs (`.next/`, `dist/`, `_fresh/`, `.output/`, etc.) are embedded in the binary's virtual filesystem and self-extracted at runtime.

backend configuration options

The `backend` field specifies which web rendering engine to embed. Valid values are `"cef"`, `"webview"`, or `"raw"`, with default `"webview"`. The CLI flag `--backend` overrides this for one build, but accepts only `cef` and `webview`; select `raw` in `deno.json`.

deepLinks current functionality limitation

Deep links are currently registered with the OS so links are routed to the app, but handling the opened URL inside a running app (delivering the URL to the code) is coming in a later release.

errorReporting.url configuration

The `errorReporting.url` field specifies the URL to `POST` a JSON error report to when uncaught exceptions, unhandled rejections, or panics occur. A native alert is shown regardless. If unset, error reporting is in "alert only" mode: uncaught errors still show a native alert, but no report is sent.

deepLinks registration per platform

Deep link registration happens at bundle time per platform: On macOS, a `CFBundleURLTypes` entry with schemes under `CFBundleURLSchemes` is added to the bundle `Info.plist` before code-signing. On Linux, an `x-scheme-handler/<scheme>` MIME type is added to the `.desktop` entry with `Exec=` forwarding the opened URL via the `%u` field code. On Windows, the bundler drops a `register-deep-links.bat` next to the launcher that writes `HKCU\Software\Classes\<scheme>` keys pointing back at the launcher, which an installer or the user runs once after install.

release.baseUrl configuration

The `release.baseUrl` field sets the base URL of the release server. The runtime fetches `<baseUrl>/latest.json` and downloads patch files relative to this URL. This is the only server URL the runtime polls automatically. `Deno.autoUpdate()` defaults to this URL but can override it per call.

app.deepLinks configuration

The `app.deepLinks` field is an array of custom URL schemes (deep links) the app registers with the OS, so opening a `<scheme>://...` link routes to the app. Each entry is a bare scheme name with no `://`. Scheme names follow RFC 3986 grammar: they must start with an ASCII letter and may otherwise contain letters, digits, `+`, `-`, and `.`. Names are lowercased during registration. The reserved schemes `http`, `https`, `file`, `ftp`, `ws`, and `wss` are rejected since registering them as app handlers would hijack normal browsing. An invalid or reserved scheme fails the build.

macos.codesignIdentity configuration

The `macos.codesignIdentity` field specifies the code-signing identity used to sign the macOS bundle, e.g. `"Developer ID Application: Acme, Inc. (TEAMID)"`, or `"-"` for an explicit ad-hoc signature. When unset, `deno desktop` still ad-hoc-signs the bundle so it has a stable code identity (required for notification permission), but the result is not distributable without further signing. Set a real Developer ID identity to produce a notarizable bundle.

app.identifier configuration field

The `app.identifier` field sets the reverse-DNS bundle/application identifier (e.g. `com.example.myapp`). It is used for the macOS `CFBundleIdentifier`, the Linux `.desktop` file identifier, and the Windows AppUserModelID. When unset, a synthetic `com.deno.desktop.<app-slug>` is generated. macOS needs a stable identifier to grant notification permission, so a real one should be set for any app that uses notifications.

deno desktop configuration location

All configuration for `deno desktop` lives in the `desktop` block in `deno.json`. Most fields are optional; a project with no `desktop` block at all still compiles using sensible defaults.

deno desktop configuration validation

Configuration is validated at the start of `deno desktop`. The `backend` field must be one of the listed values. Icon paths must resolve to existing files. Output paths must be writable. `release.baseUrl` must parse as a URL. `app.deepLinks` entries must be valid, non-reserved URL schemes. Errors are reported with the offending `deno.json` location.

app.name configuration field

The `app.name` field sets the display name of the application, used as the window title default, the macOS menu bar app name, the Windows taskbar tooltip, and the Linux `.desktop` entry name. Falls back to the `name` field at the root of `deno.json` if not set.

app.icons configuration formats

The `app.icons` field specifies per-platform icon paths relative to `deno.json`. For each platform (macos, windows, linux), you can provide a single file path (e.g. `./icons/app.icns` for macOS, `./icons/app.ico` for Windows, `./icons/app.png` for Linux), or for macOS and Linux, an array of PNG objects with `path` and `size` properties to be assembled into a multi-resolution icon at build time. `.icns` and `.ico` inputs are passed through unchanged, while PNGs are assembled into the right container per platform. If no `icons` entry is set for a platform, the default Deno icon is used.

deno desktop inspect flags

Three flags control startup behavior for deno desktop inspection: --inspect listens for a debugger and the app starts running immediately; --inspect-wait waits for a debugger to attach before running any user code; --inspect-brk waits for a debugger and breaks on the first line in both isolates. The default listen address is 127.0.0.1:9229, and can be overridden with --inspect=host:port.

Unified DevTools for deno desktop

deno desktop exposes unified DevTools, which is a single Chrome DevTools session that attaches to both V8 isolates inside a desktop app: the Deno runtime (handlers, bindings, top-level code) and the renderer (webview-side JavaScript). A single Console dropdown, one Sources panel with both threads, and one debugging session are available.

deno desktop DevTools known limitations

Known limitations of deno desktop DevTools: WebView backend has no DevTools integration; renderer Network panel does not show Deno-side fetch calls; cross-realm step-through (clicking a bindings.foo() call and stepping into the Deno handler) is not yet implemented and requires manual thread switching; --inspect-brk pauses both isolates before navigation and resuming each one is independent, so you may need to click Resume on each thread.

Cross-realm debugging limitations in deno desktop

When a webview-side bindings.foo() call enters a Deno-side handler, the two sides currently appear as separate stack traces. Cross-realm correlation (automatically stitching a renderer call into the Deno handler stack) is on the roadmap. You can switch threads in the Sources panel to follow execution manually, or tag both sides of a binding with matching console output to track execution across realms.

CDP Multiplexer in deno desktop

deno desktop runs a CDP (Chrome DevTools Protocol) multiplexer that fronts both V8 inspectors: the Deno V8 inspector (deno_core CDP) and the Renderer V8 inspector (CEF remote-debugging). The mux presents itself as one CDP browser target with two children: a page target for the renderer and a worker target for the Deno runtime.

Source maps in deno desktop DevTools

Source maps are honored on both sides in deno desktop DevTools. TypeScript files in the Deno runtime show up with their original line numbers; bundled webview JS maps back to its original source if the bundler emits maps.

DevTools Performance and Memory for deno desktop

The DevTools Performance and Memory panels for deno desktop allow profiling each isolate separately; you can switch between isolates via the target dropdown.

DevTools Network panel for deno desktop

The DevTools Network panel for deno desktop shows requests originating from the webview (the webview's fetch, XMLHttpRequest, image loads). Requests made from the Deno side via fetch are not currently surfaced.

DevTools Console for deno desktop

The DevTools Console for deno desktop includes a target dropdown at the top of the panel that switches between Renderer (the webview) and Deno (the runtime). Console output from each isolate is labelled.

deno desktop backend DevTools support

Unified DevTools support by backend: CEF backend has full unified DevTools; webview backend does not currently support unified DevTools as system webviews speak a different inspector protocol; raw backend has Deno-side --inspect only since there is no renderer to inspect. If --inspect is passed with a backend that does not support unified DevTools, the Deno side still runs an inspector and can be attached to the same way as a normal deno run --inspect session.

DevTools Sources panel for deno desktop

In the Sources panel of DevTools for deno desktop, both isolates appear in the Threads sidebar. You can set breakpoints, step through, and inspect the call stack on either side.

Starting deno desktop inspector session

To start an inspector session with deno desktop, run 'deno desktop --inspect main.ts', then open chrome://inspect or edge://inspect. The app appears as a target; click 'inspect' to open DevTools with both isolates attached.

Notifications use standard Web Notification constructor

System notifications in deno desktop apps use the standard Web Notification constructor, callable from your Deno-side code. See runtime/desktop/notifications/ for details.

File picker workaround using input type file and bindings

To pick files without a native API, use the webview's input type="file" element. The resulting File object can be sent over a binding to the Deno side for handling. The file can be read with await file.arrayBuffer() and passed as bytes to a Deno binding.

File picker dialogs not yet available as first-class API

Native file-picker and folder-picker dialogs are not yet exposed as a first-class API in deno desktop. Workarounds include using the webview's input type="file" element or drag-and-drop into the webview. A native file-picker API is on the roadmap.

Dialog functions differ from terminal Deno behavior

In a normal deno run script, alert(), confirm(), and prompt() functions read from or write to the terminal: prompt reads a line of stdin, confirm accepts y or n. In deno desktop apps, these functions are swapped out for native dialogs automatically without any code change required.

Webview-side dialogs use browser implementation

If you call alert(), confirm(), or prompt() 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.

Dialog functions block synchronously on Deno runtime thread

The alert(), confirm(), and prompt() 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.

prompt() function for native desktop dialogs

The prompt(message, defaultValue?) function shows a modal dialog with a text input plus OK and Cancel buttons. It returns the entered string, or null if the user cancelled. The defaultValue parameter is optional. It is available in deno desktop apps.

confirm() function for native desktop dialogs

The confirm(message) function shows a modal dialog with OK and Cancel buttons. It returns boolean: true for OK, false for Cancel. It is available in deno desktop apps.

alert() function for native desktop dialogs

The alert(message) function shows a modal dialog with an OK button and returns void. It is available in deno desktop apps. The current window is the parent window; clicking outside the dialog does not dismiss it; the user must click OK.

Clipboard API access via navigator.clipboard from webview

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

Desktop error reporting URL protocol requirements

The error reporting URL must use https:// or file://. Plain http:// is rejected because reports carry stack traces and runtime context that could be read by anyone on the network path. A file:// URL is useful for local testing; the runtime appends the JSON to that file path instead of making an HTTP request.

What Deno desktop automatically catches

Deno desktop apps automatically catch uncaught JavaScript exceptions in both Deno-side and renderer-side code, unhandled promise rejections, and Rust panics inside the runtime or rendering backend.

Deno desktop error reporting availability

Deno desktop error reporting is available starting in Deno v2.9.0. To use this feature, ensure you are running Deno 2.9 or later.

Deno desktop error reporting behavior

When an error is caught, the runtime shows a native alert with the error message. If a reporting URL is configured, the runtime POSTs a JSON report to that URL.

Desktop error report HTTP delivery

Reports are sent as a single POST request with no retry. If the server is down, the report is lost. For high-importance reports, consider queuing them locally and resending on the next application launch.

Binding handler errors and error reporting

Errors thrown inside a binding handler propagate to the webview side and reject the calling promise. They are not reported as uncaught errors because the webview catches them. To report them, log them yourself in the binding handler.

Deno desktop error report JSON schema

Error reports are sent as JSON with the following fields: version (1), message (string - the error's message), stack (string - the error's stack, source-mapped where possible), appVersion (string | null - Deno.desktopVersion at time of error), timestamp (ISO 8601 string in UTC), platform ("darwin" | "windows" | "linux"), arch (string - from Deno.build.arch). The Content-Type header is application/json.

Configure desktop error reporting URL in deno.json

Set the error reporting URL in deno.json under the desktop.errorReporting.url property. The configuration structure is: { "desktop": { "errorReporting": { "url": "https://errors.example.com/report" } } }

What gets reported by Deno desktop error reporting

Captured: uncaught exceptions in Deno-side code, unhandled rejections in Deno-side code, uncaught exceptions in renderer-side JavaScript (caught via renderer's error event), Rust panics in the Deno runtime, and Rust panics in the rendering backend. Not captured: console.error/console.warn calls (not errors), exceptions handled with try/catch, or errors thrown inside binding handlers (which are caught by the webview and do not surface as uncaught errors).

Cannot suppress error reporting alert from user code

There is currently no way to suppress the error alert from user code. The runtime registers its error and unhandledrejection handlers before user code runs, so preventDefault() in a listener added later does not stop the alert or report. To prevent an error from triggering the alert, handle it with try/catch or local error handling so it does not become uncaught.

Give your agent this brain