Deno.openKv() with no arguments connects to KV in Deploy
In Deno Deploy, calling await Deno.openKv() with no arguments automatically connects to the correct KV database for the current environment. No database ID or access token is required because Deno Deploy sets up the connection based on the current timeline.
Connect to remote Deno KV from local CLI
To open a managed Deno KV database from local Deno CLI apps, use the URL connector: await Deno.openKv("https://api.deno.com/v2/databases/<Database ID>/connect"). Replace <Database ID> with the actual database ID shown in the Databases table in the Deno Deploy console.
Deno KV local development uses in-memory storage by default
In local development, Deno KV data is kept in memory by default. You do not need to create or allocate a database before using the KV APIs locally. To develop against a managed Deno KV database from a local program, use the URL connector approach.
Deno KV data distribution and geographic location
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.
import.meta.url returns current module URL
import.meta.url returns the URL of the current module. For local modules run with deno run main.ts, it returns file:///dev/main.ts. For remote modules run with deno run https://example.com/main.ts, it returns https://example.com/main.ts.
import.meta.main returns if module is entry point
import.meta.main returns a boolean indicating whether the current module is the entry point to the program. When running deno run main.ts, if main.ts imports other.ts, other.ts will have import.meta.main === false while main.ts will have import.meta.main === true.
import.meta.dirname for local modules only
import.meta.dirname is only available for local modules with file:/// specifiers and returns undefined for remote modules. It returns the fully resolved path to the directory containing the current module with OS specific path separators. On Unix, deno run main.ts returns /dev/. On Windows, deno run main.ts returns C:\dev\. Remote modules return undefined.
import.meta.resolve for resolving module specifiers
import.meta.resolve(specifier) resolves specifiers relative to the current module. Example: const worker = new Worker(import.meta.resolve("./worker.ts")); It takes into account the currently applied import map, allowing resolution of "bare" specifiers. With an import map containing { "imports": { "fresh": "https://deno.land/x/fresh@1.0.1/dev.ts" } }, you can resolve: console.log(import.meta.resolve("fresh")); which returns https://deno.land/x/fresh@1.0.1/dev.ts
Deno program lifecycle events
Deno supports browser-compatible events: load (fired when page has loaded including resources), beforeunload (fired when event loop has no more work and is about to exit; scheduling async work keeps program running), unload (fired when program has no more work; scheduling async work does not keep program alive), unhandledrejection (fired for promises with no rejection handler), rejectionhandled (fired when .catch() handler added to already-rejected promise if unhandledrejection listener installed), error (fired for uncaught exceptions; registering listener prevents default behavior of printing error and terminating).
Node.js compatible program lifecycle events in Deno
Deno supports Node.js lifecycle events: process.on("beforeExit") (fired when event loop has no more work; scheduling async work continues program; counterpart to beforeunload), process.on("exit") (fired when program has no more work; async work does not keep alive; counterpart to unload), process.on("rejectionHandled") (counterpart to rejectionhandled), process.on("uncaughtException") (fired for uncaught exceptions; listener prevents default behavior; counterpart to error), process.on("unhandledRejection") (counterpart to unhandledrejection). Node.js counterparts fire immediately after Web event counterparts.
Program lifecycle listener rules for Deno
Listeners for load events can be asynchronous and will be awaited; load cannot be cancelled. Listeners for beforeunload must be synchronous and can be cancelled to keep program running. Listeners for unload must be synchronous and cannot be cancelled. Same rules apply to Node.js counterparts (beforeExit and exit).
addEventListener vs onload/onunload handlers
addEventListener and onload/onunload/onbeforeunload have different behavior. Multiple listeners added with addEventListener are all executed. However, only the last defined onload, onbeforeunload, or onunload handler will execute, overriding handlers from imported modules. Prefer addEventListener when possible for registering multiple event handlers.
Deno error classes available in Deno.errors
Deno runtime has 20 error classes accessible via Deno.errors, including Deno.errors.NotFound and Deno.errors.WriteZero. These can be caught in try-catch blocks using instanceof checks. Example: try { const file = await Deno.open("./some/file.txt"); } catch (error) { if (error instanceof Deno.errors.NotFound) { console.error("the file was not found"); } else { throw error; } }
Network operations with Deno.connect and Deno.listen
Deno runtime has built-in functions for dealing with connections to network ports: Deno.connect(options) connects to a hostname and port; Deno.listen(options) announces on a local transport address.
Subprocesses with Deno.Command
Deno runtime comes with built-in functions for spinning up subprocesses. Deno.Command is used to create subprocesses.