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

runtime apis

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

Deno.metrics() provides internal operation and data statistics

Deno.metrics() returns an object containing internal counters for various statistics including: opsDispatched, opsDispatchedSync, opsDispatchedAsync, opsDispatchedAsyncUnref, opsCompleted, opsCompletedSync, opsCompletedAsync, opsCompletedAsyncUnref, bytesSentControl, bytesSentData, and bytesReceived. These metrics track operations and data flow within the Deno runtime.

Resources (rid) are Deno's file descriptor equivalent

Resources, or rids, are Deno's version of file descriptors. They are integer values used to refer to open files, sockets, and other concepts. Resources can be queried with Deno.resources() to get a mapping of resource IDs to their type names like 'stdin', 'stdout', and 'stderr'. Resources can be closed with Deno.close(rid).

Deno.resources() example returns stdin, stdout, stderr by default

Calling Deno.resources() returns an object mapping resource IDs to their types. By default, { 0: 'stdin', 1: 'stdout', 2: 'stderr' } are present. After closing resource 0 with Deno.close(0), the object becomes { 1: 'stdout', 2: 'stderr' }.

Linux and Deno architectural analogy

Deno's architecture maps to Linux concepts as follows: Processes map to Web Workers, syscalls map to Ops, file descriptors (fd) map to resource ids (rid), the Linux scheduler maps to Tokio, userland libraries map to @std from jsr.io, /proc/$$/stat maps to Deno.metrics(), and man pages map to deno types and https://docs.deno.com documentation.

Deno.autoUpdate() availability

Deno.autoUpdate() is available starting in Deno 2.9.0. It polls a release server for new versions, downloads binary-diff patches, applies them to the runtime dylib, and stages the result for the next launch. If the next launch fails, the runtime rolls back to the previous version automatically.

Auto-update platform support

Applying staged updates and rolling back on a failed launch currently run on macOS and Linux only. On Windows, patches are downloaded and staged, but the launcher does not swap them in, so updates do not take effect. Windows auto-update is not yet supported.

Auto-update prerequisites in deno.json

Two pieces of configuration are required for auto-update: a 'version' field with the app version string, and a 'desktop.release.baseUrl' field with the release server URL. Both are baked into the compiled binary. Example: {"version": "1.4.0", "desktop": {"release": {"baseUrl": "https://releases.example.com/my-app"}}}

Deno.desktopVersion API

Deno.desktopVersion is a runtime property that exposes the version string baked into the compiled binary. It returns the version string (e.g., "1.4.0") or null if no version was set. Under deno run, it is always null since a non-compiled program has no baked-in version.

Deno.autoUpdate() behavior when desktopVersion is null

If Deno.desktopVersion is null, Deno.autoUpdate() is a no-op: the runtime warns once and returns. This occurs both when no version is set in deno.json and under deno run. Deno.autoUpdate() does not throw, so you can leave the call in your code and run the same entry point with deno run during development.

Deno.autoUpdate() options table

Deno.autoUpdate() accepts an options object with the following fields: url (string, required if no desktop.release.baseUrl in deno.json), interval (number in milliseconds, poll interval, omit for single check only), onUpdateReady (function (version: string) => void, called once a patch is applied and staged for next launch), onRollback (function (reason: string) => void, called shortly after if previous launch failed), publicKey (string, base64 Ed25519 public key, when set the manifest must be signed).

Deno.autoUpdate() URL string shorthand

Deno.autoUpdate() can be called with just a URL string for a single one-shot check on startup: Deno.autoUpdate("https://releases.example.com/my-app")

Deno.autoUpdate() with options example

Example of Deno.autoUpdate() with polling options: Deno.autoUpdate({url: "https://releases.example.com/my-app", interval: 60 * 60 * 1000, onUpdateReady(version) { console.log("Update", version, "ready; will apply on next launch"); }, onRollback(reason) { console.warn("Previous launch failed; rolled back:", reason); }});

Auto-update manifest format

The runtime fetches <url>/latest.json and parses it as JSON with the following structure: {"version": "<latest-version>", "patches": {"<from-version>": {"name": "<patch-filename>", "sha256": "<64-hex-chars>"}, ...}}. The version field is the latest available version compared with Deno.desktopVersion. The patches field is a map of from-version to {name, sha256} where name is the patch filename relative to the manifest URL and sha256 is the lowercase hex SHA-256 of the patch bytes.

Auto-update SHA-256 requirement

The sha256 field in patch entries is required. The runtime refuses to apply a patch whose bytes do not hash to the declared value, so a tampered or truncated download can never be applied.

Auto-update unsupported versions

Old versions can be omitted from the patches map in the manifest. Users on versions without a patch entry log a 'no patch available for X' message and stay on their current version.

Auto-update HTTPS requirement

The update URL must use HTTPS. The runtime refuses to poll a plaintext endpoint.

Signed auto-update manifest format

When a publicKey is configured in Deno.autoUpdate(), the manifest must be an envelope: {"signed": "{\"version\":\"1.5.0\",\"patches\":{ … }}", "signature": "<base64 Ed25519 signature>"}. The runtime verifies the signature over the exact bytes of the signed string using the publicKey, then parses the signed string as the trusted manifest.

Signed manifest with publicKey example

Example of Deno.autoUpdate() with a signed manifest: Deno.autoUpdate({url: "https://releases.example.com/my-app", publicKey: "<base64-encoded 32-byte Ed25519 public key>"});

Auto-update flow steps

The auto-update flow: 1) Fetch manifest via GET <url>/latest.json, silently return on non-2xx response. 2) Compare versions: if manifest.version equals Deno.desktopVersion, nothing to do. 3) Look up patch at manifest.patches[Deno.desktopVersion]. 4) Download patch via GET <url>/<name>. 5) Verify bytes against sha256 and refuse on mismatch, then apply binary diff using qbsdiff, sanity-check patched bytes as native binary. 6) Write patched dylib as <dylib>.update. 7) Fire onUpdateReady callback. The running dylib is untouched until next launch; on restart, the launcher swaps the staged update into place first.

Auto-update rollback mechanism

The launcher uses three files next to the runtime dylib for rollback: <dylib>.update (staged patch), <dylib>.backup (previous dylib), <dylib>.update-ok (success sentinel). If <dylib>.update exists, the launcher copies current dylib to <dylib>.backup, swaps the staged update, and starts the new version. On successful boot, the runtime writes <dylib>.update-ok. On a later launch, if both <dylib>.backup and <dylib>.update-ok exist, the update is confirmed good and both files are cleaned up. If <dylib>.backup exists but <dylib>.update-ok does not, the last update crashed, so the launcher restores <dylib>.backup and the next autoUpdate call fires onRollback.

Generating bsdiff patches

A patch is a bsdiff of the runtime dylib between two releases. Use the classic bsdiff CLI: bsdiff old-dylib new-dylib patch-1.4.0-to-1.5.0.bin. Then compute the sha256: shasum -a 256 patch-1.4.0-to-1.5.0.bin. Add the patch's name and sha256 to latest.json and upload both to the release server.

Multi-architecture auto-update manifests

For multiple architectures (macOS arm64, x86_64; Windows x86_64; Linux arm64, x86_64), generate patches per-architecture. Either serve different manifests based on user-agent, or include all patches under architecture-specific keys: {"version": "1.5.0", "patches": {"1.4.0": {"name": "patch-1.4.0-to-1.5.0.bin", "sha256": "<hash>"}}}. Pick the correct URL on the client using Deno.build.os and Deno.build.arch.

Multi-architecture auto-update example

Example of picking architecture-specific manifest: const arch = Deno.build.os + "-" + Deno.build.arch; Deno.autoUpdate({url: "https://releases.example.com/" + arch, interval: 60 * 60 * 1000});

Auto-update best practice: sign manifests

Sign manifests with an Ed25519 key and configure the publicKey in Deno.autoUpdate(). TLS plus the required per-patch sha256 stop tampered patches, but anyone able to serve from your URL could push a validly-hashed malicious patch. For defense in depth, use manifest signing and keep the private key off the release host.

Auto-update best practice: test patches

Test patches against a real install before publishing the manifest. A patch that applies cleanly but produces a non-bootable binary triggers rollback after a failed launch, so users see a brief startup failure. Run the patched binary in CI before publishing.

Auto-update best practice: poll interval

Choose a sensible interval for polling. Hourly is fine for most apps. Polling more often than every few minutes is wasteful for both you and your users.

Auto-update best practice: handle onRollback

Handle the onRollback callback. A rollback signals that a recent release was broken on at least one machine. Log it to telemetry so you notice broken releases quickly.

win.bind() exposes Deno functions to webview

win.bind(name, handler) exposes a Deno-side function to the webview. From the webview, call it as bindings.<name>(args), and the call returns a Promise that resolves with the handler's return value.

Bindings use in-process channels, not IPC

Bindings are not IPC. The Deno runtime and the rendering backend run as threads/processes inside the same address space (CEF) or coordinated process group (WebView). Calls go through in-process channels dispatched from the backend's run loop. Arguments and results are encoded as they cross the realm boundary, but the transport is in-process with no socket or cross-process scheduling.

bindings is a Proxy that creates functions on demand

The bindings object on the webview side is a Proxy. Any property access creates a function on demand. The proxy does not validate names at property access time; accessing an unregistered binding name throws only when you call it.

Binding arguments and return values encoded as JSON

Arguments and return values are encoded as JSON as they cross between the webview and the Deno runtime. Plain objects, arrays, strings, numbers, booleans, and null are passed as-is. Uint8Array is supported for binary data. undefined and optional properties are dropped during serialization. Date, Map, Set, RegExp, typed arrays other than Uint8Array, and ArrayBuffer are not preserved and must be converted to JSON-compatible shapes before sending. Functions, DOM nodes, prototypes, and cyclic references are not transferable. Errors thrown by a handler are delivered as {name, message, stack} objects, not as Error instances.

Binding handlers can be sync or async

Handlers can be sync or async. The webview always sees a Promise regardless of whether the handler is synchronous or asynchronous.

Errors in bindings are delivered as plain objects

A handler that throws, synchronously or via a rejected promise, causes the webview-side call to reject. The error reaches the webview as a plain {name, message, stack} object. To distinguish error types, check the error.name property.

win.unbind() removes a binding

win.unbind(name) removes a binding. Subsequent calls to the unbound binding reject.

Bindings inherit Deno runtime permissions

Bindings run inside the Deno runtime, so they inherit the process's permissions. A binding that calls Deno.readTextFile requires --allow-read to have been granted at startup. The webview cannot escalate the runtime's permissions through bindings.

Bindings are per-window

Bindings are per-window. A binding registered on one window is not callable from another window's webview. To share a binding across windows, register it on each window separately.

Type safety for bindings using a shared declaration file

There is no built-in type bridge between the Deno side's win.bind() and the webview side's bindings.<name>(). To achieve type safety, create a shared declaration file with a Bindings interface. Reference it from the webview's tsconfig/Deno project config and use the same Bindings interface to type-check win.bind() calls. Mismatches will be caught at compile time on the Deno side.

Electron to Deno desktop migration guide

Migration from Electron to deno desktop: Electron's ipcMain.handle('channel', (e, ...args) => result) maps to win.bind('channel', (...args) => result); Electron's ipcRenderer.invoke('channel', ...args) maps to bindings.channel(...args); Electron's contextBridge.exposeInMainWorld('api', {...}) is not needed as bindings is exposed by default. The event object Electron passes as the first argument has no equivalent because there is no separate process to attribute the call to.

Example: binding to read and save settings

Deno side: win.bind("readSettings", async () => { const text = await Deno.readTextFile("settings.json"); return JSON.parse(text); }); win.bind("saveSettings", async (settings) => { await Deno.writeTextFile("settings.json", JSON.stringify(settings, null, 2)); }); Webview side: const settings = await bindings.readSettings(); settings.theme = "dark"; await bindings.saveSettings(settings); This example shows how to expose file I/O operations to the webview via bindings.

Deno.BrowserWindow.openDevtools() API

The Deno.BrowserWindow.openDevtools() API opens a DevTools window inside the app. Call win.openDevtools() to open DevTools for both isolates (default); win.openDevtools({ deno: false }) for renderer only; win.openDevtools({ renderer: false }) for Deno runtime only.

getNativeWindow() bridge between window and WebGPU

The bridge between a window and WebGPU is Deno.BrowserWindow.getNativeWindow(), which returns a Deno.UnsafeWindowSurface. This surface exposes a WebGPU canvas context, so the context.configure() / getCurrentTexture() / present() flow used in browsers works against a real OS window.

Run TypeScript directly without build step

Deno runs .ts files directly without requiring tsc compilation or a build step. TypeScript support is built-in.

Deno secure by default - no permissions granted initially

Deno code runs in a sandbox with no file, network, or environment access until you grant it. You must use permission flags like --allow-net to enable network access.

Deno.serve is a web-standard HTTP server API

Deno.serve is a built-in HTTP server based on web standards, using Request and Response objects that align with platform standards rather than framework-specific APIs.

Works with existing Node.js projects and npm packages

Deno can run in repositories that already have package.json and node_modules. It supports mixing npm: imports (for npm packages) with native ES modules, enabling gradual migration from Node.js.

Deno is secure by default and requires permission grants

Deno is secure by default. The first time an app touches the network, filesystem, or environment, Deno prompts for permission. Grant permissions upfront with flags such as -N for network, -R for read, -E for environment, or -A for all permissions (equivalent to Node behavior).

Deno is sandboxed by default, unlike Bun

Deno runs code with a sandbox by default and prompts for permissions the first time the program needs access to the network, file system, or environment. This differs from Bun, which runs with full access by default. Use deno run -A to grant all permissions up front to match Bun's behavior, then tighten the flags later.

Deno.serve replaces Bun.serve for HTTP servers

Both Deno.serve and Bun.serve accept a fetch-style handler function that receives a Request and returns a Response. The differences are: Bun.serve takes a single options object with a fetch property, while Deno.serve takes the handler as a direct argument optionally preceded by an options bag. Bun passes the server object as the handler's second argument; Deno passes connection info instead. Bun's routes option has no built-in counterpart in Deno.serve; use URLPattern or a framework for routing.

Deno file APIs replace Bun.file

Bun.file() returns a lazy file reference with .text() and .json() methods. In Deno, read files directly with Deno.readTextFile(), or use Deno.open when you need a handle for streaming. For higher-level helpers like copy, move, walk, and exists, use the @std/fs package or node:fs.

node:test and node:assert replace bun:test

bun test runs Jest-style tests from bun:test. Deno supports the node:test built-in, so the describe and it structure carries over directly. Pair it with node:assert for assertions. If you want to keep Bun's Jest-style expect assertions, import expect from @std/expect. Deno's own Deno.test runner is also available.

dax library replaces Bun's $ shell template literal

Bun's $ template-literal shell has a near-identical counterpart in dax, available from jsr:@david/dax. For plain subprocess control without a shell layer, use the built-in Deno.Command API.

DENO_AUTH_TOKENS environment variable format

The Deno CLI looks for an environment variable named DENO_AUTH_TOKENS to determine authentication tokens for requesting remote modules. The value is a semicolon-delimited list of tokens. Each token is either a bearer token in the format {token}@{hostname[:port]} or basic auth data in the format {username}:{password}@{hostname[:port]}.

Bearer token example for single repository

A single bearer token for deno.land would be formatted as: DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land

Basic auth token example for single repository

A single basic auth token for deno.land would be formatted as: DENO_AUTH_TOKENS=username:password@deno.land

Multiple tokens in DENO_AUTH_TOKENS

Multiple tokens are delimited by semicolons. Example: DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land;f1e2d3c4b5a6@example.com:8080;username:password@deno.land

How Deno uses authentication tokens

When Deno fetches a remote module, if the hostname matches a hostname in DENO_AUTH_TOKENS, Deno sets the Authorization header to either Bearer {token} or Basic {base64EncodedData}, allowing the remote server to recognize the authorized request.

DENO_AUTH_TOKENS for GitHub raw content

To access modules in private GitHub repositories, use the personal access token scoped to raw.githubusercontent.com in DENO_AUTH_TOKENS. Example: DENO_AUTH_TOKENS=a1b2c3d4e5f6@raw.githubusercontent.com

GitHub returns 404 for unauthorized access

When a GitHub token is incorrect or the user does not have access to a private module, GitHub returns a 404 Not Found status instead of an unauthorized status. If getting module not found errors, check the DENO_AUTH_TOKENS environment variable and personal access token settings.

Deno KV data distribution and storage regions

Deno KV databases are replicated across at least three data centers in the primary region, Northern Virginia (us-east4). Write operations are durably stored in a quorum of data centers within the primary region with read replicas in Europe and Asia. Data written to KV is stored in and transits through the US. Data is encrypted in transit and at rest, and KV is isolated per project.

Deno KV in Deno Deploy requires database assignment

Deno KV is a Key Value database supported in Deno Deploy as a database engine option within the databases feature. To use it, you must first provision a database instance from your organization dashboard by clicking Databases in the navigation bar, then clicking Provision Database, selecting Deno KV as the database engine, providing a memorable name, and saving. After provisioning, you assign the database to an app by clicking Assign next to the database and selecting the app from the dropdown.

Give your agent this brain