# Deno User Guide

Deno is a modern JavaScript, TypeScript, and WebAssembly runtime built on V8, Rust, and Tokio. It runs scripts in a secure sandbox by default, ships native TypeScript support without a separate compiler, and includes a complete toolchain — formatter, linter, test runner, benchmarker, bundler, documentation generator, package manager, and compiler — in a single executable. Programs that ran in Node.js can usually run in Deno with minimal changes via the built-in `node:` and `npm:` import schemes.

This guide walks you from installation through everyday use to advanced workflows. Written from the Deno 2.7.12 source at commit `7529c84` (2026-04-17).

---

## 1. Quick Start

The fastest path from zero to a running Deno program.

### 1.1 Install Deno (60 Seconds)

=== "macOS / Linux"

    ```bash
    curl -fsSL https://deno.land/install.sh | sh
    ```

=== "Windows (PowerShell)"

    ```powershell
    irm https://deno.land/install.ps1 | iex
    ```

=== "Homebrew"

    ```bash
    brew install deno
    ```

=== "Cargo (from source)"

    ```bash
    cargo install deno --locked
    ```

Verify the installation:

```bash
deno --version
```

Expected output:

```text
deno 2.7.12 (stable, release, x86_64-unknown-linux-gnu)
v8 13.7.152.6
typescript 5.7.3
```

> [!TIP]
> Deno installs as a single binary with zero external dependencies. If you need to install in a CI pipeline, the one-liner shell scripts above are all you need — no package manager lock files, no `node_modules`, no post-install hooks.

### 1.2 Hello World

Create a file called `hello.ts`:

```typescript
console.log("Hello from Deno!");
```

Run it:

```bash
deno run hello.ts
```

```text
Hello from Deno!
```

TypeScript works out of the box with no `tsconfig.json`, no `tsc`, and no build step.

### 1.3 Fetch Data from the Network

```typescript
// fetch_example.ts
const response = await fetch("https://api.github.com/zen");
const text = await response.text();
console.log(`GitHub says: ${text}`);
```

```bash
deno run --allow-net=api.github.com fetch_example.ts
```

```text
GitHub says: Speak like a human.
```

Notice the `--allow-net` flag — Deno blocks network access by default. You must explicitly grant permissions. This is the cornerstone of Deno's security model.

### 1.4 Run a Remote Script

Deno can run scripts directly from URLs:

```bash
deno run https://examples.deno.land/hello-world.ts
```

```text
Hello, World!
```

The module is downloaded, cached locally, and executed. Subsequent runs use the cached version unless you pass `--reload`.

### 1.5 Initialize a New Project

```bash
deno init my_project
```

```text
✅ Project initialized

  Run these commands to get started

  cd my_project
  deno run main.ts
  deno task dev
```

This creates a `deno.json` configuration file, a `main.ts` entry point, and a `main_test.ts` test file.

---

## 2. Installation

### 2.1 System Requirements

| Platform | Architectures | Minimum |
|----------|---------------|---------|
| macOS | x86_64, aarch64 (Apple Silicon) | macOS 10.15+ |
| Linux | x86_64, aarch64 | glibc 2.31+ or musl |
| Windows | x86_64 | Windows 10+ |

Deno is a single static binary. It requires no system libraries beyond what ships with the OS.

### 2.2 Installation Methods

#### Shell Installer (Recommended)

**macOS / Linux:**

```bash
curl -fsSL https://deno.land/install.sh | sh
```

**Windows (PowerShell):**

```powershell
irm https://deno.land/install.ps1 | iex
```

To install a specific version:

```bash
curl -fsSL https://deno.land/install.sh | sh -s v2.7.12
```

> [!IMPORTANT]
> After installation, add Deno to your PATH. The installer prints the exact commands for your shell. For bash/zsh, add `export DENO_INSTALL="$HOME/.deno"` and `export PATH="$DENO_INSTALL/bin:$PATH"` to your shell profile (`~/.bashrc`, `~/.zshrc`, or `~/.bash_profile`).

#### Package Managers

```bash
# Homebrew (macOS/Linux)
brew install deno

# Chocolatey (Windows)
choco install deno

# Scoop (Windows)
scoop install deno

# WinGet (Windows)
winget install DenoLand.Deno

# Nix
nix-shell -p deno

# asdf
asdf plugin add deno
asdf install deno 2.7.12
asdf global deno 2.7.12
```

#### Docker

```bash
docker run -it denoland/deno:2.7.12 deno run https://examples.deno.land/hello-world.ts
```

For a project:

```dockerfile
FROM denoland/deno:2.7.12

WORKDIR /app
COPY . .
RUN deno cache main.ts

CMD ["deno", "run", "--allow-net", "--allow-read", "main.ts"]
```

#### Build from Source

```bash
git clone https://github.com/denoland/deno.git
cd deno
cargo build --release
./target/release/deno --version
```

Requires Rust 1.77+ and the `protobuf-compiler` system package.

### 2.3 Upgrading

```bash
deno upgrade
```

```text
Looking up latest version
Found latest version 2.7.12
Deno is already up to date
```

Upgrade to a specific version:

```bash
deno upgrade --version 2.7.12
```

Upgrade to the canary (bleeding-edge) channel:

```bash
deno upgrade --canary
```

> [!WARNING]
> Canary builds are compiled from the latest commit on `main` and may contain breaking changes or unfinished features. Do not use canary in production. Set `DENO_CANARY=1` in your environment to make `deno upgrade` default to the canary channel.

### 2.4 Shell Completions

Generate completions for your shell and source them:

```bash
# Bash
deno completions bash > /usr/local/etc/bash_completion.d/deno

# Zsh
deno completions zsh > ~/.zsh/completions/_deno

# Fish
deno completions fish > ~/.config/fish/completions/deno.fish

# PowerShell
deno completions powershell >> $PROFILE
```

### 2.5 Uninstalling

Remove the binary and cache:

```bash
rm -rf ~/.deno
# or remove the binary directly
rm $(which deno)
```

On Windows, delete `%USERPROFILE%\.deno` and remove the PATH entry.

---

## 3. Configuration

Deno uses a `deno.json` (or `deno.jsonc`) configuration file at the project root. This file is optional — every setting has sensible defaults — but it centralizes project configuration in one place.

### 3.1 Creating a Configuration File

```bash
deno init
```

This creates a minimal `deno.json`:

```json
{
  "tasks": {
    "dev": "deno run --watch main.ts"
  }
}
```

### 3.2 Configuration File Reference

A comprehensive `deno.json` with all major sections:

```jsonc
{
  // Import map — resolve bare specifiers
  "imports": {
    "@std/": "jsr:@std/",
    "oak": "jsr:@oak/oak@^17",
    "lodash": "npm:lodash@^4.17"
  },

  // Tasks (like npm scripts)
  "tasks": {
    "dev": "deno run --watch --allow-net main.ts",
    "start": "deno run --allow-net --allow-read main.ts",
    "test": "deno test --allow-read",
    "lint": "deno lint",
    "fmt": "deno fmt",
    "build": "deno compile --output=dist/app main.ts"
  },

  // TypeScript compiler options
  "compilerOptions": {
    "strict": true,
    "lib": ["deno.window", "deno.unstable"],
    "jsx": "react-jsx",
    "jsxImportSource": "react",
    "experimentalDecorators": true
  },

  // Formatter settings
  "fmt": {
    "useTabs": false,
    "lineWidth": 80,
    "indentWidth": 2,
    "singleQuote": false,
    "proseWrap": "always",
    "include": ["src/"],
    "exclude": ["vendor/"]
  },

  // Linter settings
  "lint": {
    "include": ["src/"],
    "exclude": ["vendor/"],
    "rules": {
      "tags": ["recommended"],
      "include": ["ban-untagged-todo", "no-unused-vars"],
      "exclude": ["no-explicit-any"]
    }
  },

  // Test runner settings
  "test": {
    "include": ["tests/"],
    "exclude": ["tests/fixtures/"]
  },

  // Benchmark settings
  "bench": {
    "include": ["benches/"],
    "exclude": []
  },

  // Lock file (true by default)
  "lock": true,

  // Node modules mode
  "nodeModulesDir": "auto",

  // Workspace (monorepo)
  "workspace": ["./packages/core", "./packages/cli"],

  // Unstable features
  "unstable": ["kv", "cron", "temporal"]
}
```

> [!NOTE]
> For the full configuration schema with every supported key and its valid values, see the **Admin Guide** section on Configuration Mastery. This User Guide covers the options most people need day-to-day.

### 3.3 Import Maps

Import maps let you use bare specifiers (like `"lodash"`) instead of full URLs. They live in the `"imports"` field of `deno.json`:

```json
{
  "imports": {
    "@std/path": "jsr:@std/path@^1",
    "@std/assert": "jsr:@std/assert@^1",
    "express": "npm:express@^4.18",
    "~/": "./src/"
  }
}
```

Then in your code:

```typescript
import { join } from "@std/path";
import { assertEquals } from "@std/assert";
import express from "express";
import { helper } from "~/utils/helper.ts";
```

Scoped imports let you remap dependencies of dependencies:

```json
{
  "imports": {
    "lodash": "npm:lodash@4.17.21"
  },
  "scopes": {
    "npm:some-package@1/": {
      "lodash": "npm:lodash@3.10.0"
    }
  }
}
```

### 3.4 Tasks

Tasks are the Deno equivalent of npm scripts. Define them in `deno.json` and run with `deno task`:

```json
{
  "tasks": {
    "dev": "deno run --watch --allow-net main.ts",
    "start": "deno run --allow-net --allow-read main.ts",
    "test": "deno test --allow-read --parallel",
    "test:coverage": "deno test --allow-read --coverage=cov && deno coverage cov",
    "lint": "deno lint",
    "fmt": "deno fmt --check",
    "check": "deno check main.ts",
    "build": "deno compile --output dist/app main.ts",
    "clean": "rm -rf dist/ cov/"
  }
}
```

```bash
deno task dev
```

```text
Task dev deno run --watch --allow-net main.ts
Watcher Process started.
Listening on http://localhost:8000
```

Tasks support shell syntax including pipes, `&&`, `||`, and environment variables:

```json
{
  "tasks": {
    "ci": "deno lint && deno fmt --check && deno test --parallel",
    "greet": "echo Hello $USER"
  }
}
```

List all available tasks:

```bash
deno task
```

```text
Available tasks:
- dev
    deno run --watch --allow-net main.ts
- start
    deno run --allow-net --allow-read main.ts
- test
    deno test --allow-read --parallel
```

### 3.5 Lock Files

Deno generates a `deno.lock` (v2 format) file automatically to ensure reproducible builds:

```bash
# Generate or update the lock file
deno cache --lock=deno.lock main.ts

# Verify integrity against the lock file
deno cache --lock=deno.lock --frozen main.ts
```

The lock file records the hash of every remote dependency. If a dependency changes upstream (supply-chain attack, accidental update), Deno refuses to run:

```text
error: The source code is invalid, as it does not match the expected hash in the lock file.
  Specifier: https://deno.land/std@0.224.0/path/mod.ts
```

To update:

```bash
deno cache --lock=deno.lock --lock-write main.ts
```

Disable lock files entirely in `deno.json`:

```json
{
  "lock": false
}
```

### 3.6 Workspaces (Monorepos)

Deno supports monorepos through workspace configuration:

```jsonc
// deno.json (root)
{
  "workspace": ["./packages/core", "./packages/cli", "./packages/web"]
}
```

```jsonc
// packages/core/deno.json
{
  "name": "@myorg/core",
  "version": "1.0.0",
  "exports": "./mod.ts"
}
```

```jsonc
// packages/cli/deno.json
{
  "name": "@myorg/cli",
  "version": "1.0.0",
  "exports": "./mod.ts",
  "imports": {
    "@myorg/core": "jsr:@myorg/core@^1"
  }
}
```

Each workspace member has its own `deno.json` but shares the root lock file and can reference sibling packages.

### 3.7 TypeScript Configuration

Deno ships with built-in TypeScript support. The `compilerOptions` field in `deno.json` accepts a subset of `tsconfig.json` options:

```json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "exactOptionalPropertyTypes": true,
    "lib": ["deno.window"],
    "jsx": "react-jsx",
    "jsxImportSource": "preact"
  }
}
```

Supported `lib` values include `deno.window`, `deno.worker`, `deno.unstable`, `deno.ns`, and `esnext`. These control which type declarations are available.

> [!TIP]
> You do not need a `tsconfig.json` file. Deno's defaults (`strict: true`, targeting `esnext`) are intentionally modern. Only add `compilerOptions` when you need JSX, decorators, or specific strictness tweaks.

### 3.8 Node Modules Directory

By default, Deno caches npm packages globally in `DENO_DIR`. If you prefer a local `node_modules` directory (for compatibility with tools that expect it):

```json
{
  "nodeModulesDir": "auto"
}
```

| Value | Behavior |
|-------|----------|
| `"none"` | Global cache only (default) |
| `"auto"` | Create `node_modules` automatically when npm packages are used |
| `"manual"` | Create `node_modules` only when you run `deno install` |

---

## 4. Core Usage

### 4.1 Running Scripts

#### Basic Execution

```bash
deno run main.ts
```

Deno runs TypeScript, JavaScript, JSX, and TSX files natively. File extensions determine the parser:

| Extension | Language |
|-----------|----------|
| `.ts` | TypeScript |
| `.tsx` | TypeScript + JSX |
| `.js` | JavaScript |
| `.jsx` | JavaScript + JSX |
| `.mjs` | JavaScript (ES module) |
| `.mts` | TypeScript (ES module) |
| `.wasm` | WebAssembly |

#### Watch Mode

Automatically restart when files change:

```bash
deno run --watch main.ts
```

```text
Watcher Process started.
Listening on http://localhost:8000
Watcher File change detected! Restarting!
Listening on http://localhost:8000
```

Watch specific files or directories:

```bash
deno run --watch=src/,config/ main.ts
```

#### Running Remote Modules

```bash
# From URL
deno run https://deno.land/std/examples/welcome.ts

# From JSR
deno run jsr:@std/http/file-server

# Force re-download
deno run --reload https://deno.land/std/examples/welcome.ts
```

#### Evaluating Code Inline

```bash
deno eval "console.log(1 + 2)"
```

```text
3
```

```bash
deno eval --ext=ts "const x: number = 42; console.log(x)"
```

```text
42
```

### 4.2 The Permission System

Deno runs in a secure sandbox by default. All access to the outside world requires explicit permission grants.

#### Permission Flags

| Flag | Scope | Example |
|------|-------|---------|
| `--allow-read` | File system reads | `--allow-read=/etc,/tmp` |
| `--allow-write` | File system writes | `--allow-write=./output` |
| `--allow-net` | Network access | `--allow-net=api.github.com:443` |
| `--allow-env` | Environment variables | `--allow-env=HOME,PATH` |
| `--allow-run` | Subprocess execution | `--allow-run=git,npm` |
| `--allow-sys` | System info (hostname, OS, etc.) | `--allow-sys=hostname,osRelease` |
| `--allow-ffi` | Foreign function interface | `--allow-ffi=./libfoo.so` |
| `--allow-import` | Remote module imports | `--allow-import=deno.land,jsr.io` |
| `-A` / `--allow-all` | Everything | (use sparingly) |

#### Deny Flags

Deny flags take precedence over allow flags, enabling "allow everything except":

| Flag | Purpose |
|------|---------|
| `--deny-read` | Block specific paths |
| `--deny-write` | Block specific paths |
| `--deny-net` | Block specific hosts |
| `--deny-env` | Block specific variables |
| `--deny-run` | Block specific executables |
| `--deny-sys` | Block specific system info |
| `--deny-ffi` | Block FFI for specific libraries |

> [!WARNING]
> `-A` / `--allow-all` disables the entire permission sandbox. Only use this for trusted code during development. In production, always specify the minimum permissions needed. The deny flags cannot override `--allow-all`.

#### Granular Permission Scoping

Permissions accept comma-separated allow-lists:

```bash
# Allow reading only the data directory and /etc/hosts
deno run --allow-read=./data,/etc/hosts main.ts

# Allow network to specific hosts and ports
deno run --allow-net=api.github.com:443,localhost:8080 main.ts

# Allow running only git and curl
deno run --allow-run=git,curl main.ts

# Allow reading specific env vars
deno run --allow-env=DATABASE_URL,API_KEY main.ts
```

#### Combining Allow and Deny

```bash
# Allow all file reads EXCEPT /etc/shadow and /etc/passwd
deno run --allow-read --deny-read=/etc/shadow,/etc/passwd main.ts

# Allow all network EXCEPT internal services
deno run --allow-net --deny-net=192.168.0.0/16,10.0.0.0/8 main.ts
```

> [!NOTE]
> Deny flags always win. If both `--allow-read=/etc` and `--deny-read=/etc/shadow` are set, Deno allows reading everything under `/etc` except `/etc/shadow`.

#### Interactive Permission Prompts

When you run a script without permission flags and it requests access, Deno prompts:

```text
┌ ⚠️  Deno requests net access to "api.github.com:443".
├ Requested by `fetch()` API.
├ Run again with --allow-net to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net)
```

This lets you run untrusted scripts and approve permissions one at a time. In CI, the prompt is skipped and access is denied (non-interactive mode).

### 4.3 Module System

#### ES Modules Everywhere

Deno uses standard ES modules. Every file is a module. No CommonJS (`require`), no global namespace pollution.

```typescript
// math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}
```

```typescript
// main.ts
import { add, multiply } from "./math.ts";

console.log(add(2, 3));       // 5
console.log(multiply(4, 5));   // 20
```

> [!IMPORTANT]
> Deno requires file extensions in local imports. Write `import { add } from "./math.ts"`, not `import { add } from "./math"`. This matches the web platform and avoids ambiguity.

#### Import Sources

Deno supports three import sources:

```typescript
// 1. Local files (relative or absolute path)
import { helper } from "./utils/helper.ts";

// 2. JSR (JavaScript Registry) — preferred for Deno-native packages
import { serve } from "jsr:@std/http@^1/serve";
import { parse } from "jsr:@std/flags@^1";

// 3. npm packages — full Node.js ecosystem access
import express from "npm:express@^4.18";
import chalk from "npm:chalk@^5";

// 4. HTTPS URLs (pin versions via lock file)
import { z } from "https://deno.land/x/zod@v3.22.4/mod.ts";
```

#### Re-exporting

```typescript
// mod.ts — barrel file
export { serve } from "./server.ts";
export { Router } from "./router.ts";
export type { Route, Handler } from "./types.ts";
```

#### Dynamic Imports

```typescript
const module = await import("./plugins/analytics.ts");
module.track("pageview");
```

### 4.4 Standard Library

The Deno Standard Library (`@std`) provides reviewed, stable modules. Import from JSR:

```typescript
import { join, resolve, basename } from "@std/path";
import { assertEquals } from "@std/assert";
import { parse as parseFlags } from "@std/flags";
import { serveDir } from "@std/http/file-server";
import { copy } from "@std/fs/copy";
import { readLines } from "@std/io/read-lines";
import { delay } from "@std/async/delay";
import { format } from "@std/datetime/format";
import { encodeBase64 } from "@std/encoding/base64";
import { crypto } from "@std/crypto";
```

Add standard library packages to your project:

```bash
deno add jsr:@std/path jsr:@std/assert jsr:@std/http
```

This updates the `imports` map in `deno.json`:

```json
{
  "imports": {
    "@std/assert": "jsr:@std/assert@^1.0.12",
    "@std/http": "jsr:@std/http@^1.0.16",
    "@std/path": "jsr:@std/path@^1.0.10"
  }
}
```

### 4.5 npm Compatibility

Deno can use the entire npm ecosystem.

#### Importing npm Packages

```typescript
// Using npm: specifier directly
import express from "npm:express@^4.18";
import chalk from "npm:chalk@^5";
import _ from "npm:lodash@^4.17";
```

Or add them to your import map:

```bash
deno add npm:express npm:chalk
```

```json
{
  "imports": {
    "chalk": "npm:chalk@^5.4.1",
    "express": "npm:express@^4.21.2"
  }
}
```

Then import cleanly:

```typescript
import express from "express";
import chalk from "chalk";
```

#### Full Express.js Example

```typescript
// server.ts
import express from "npm:express@^4.18";

const app = express();

app.get("/", (_req, res) => {
  res.json({ message: "Hello from Deno + Express!" });
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});
```

```bash
deno run --allow-net --allow-read --allow-env server.ts
```

```text
Server running on http://localhost:3000
```

### 4.6 Node.js Compatibility

Deno polyfills 48 Node.js built-in modules. Import them with the `node:` prefix:

```typescript
import fs from "node:fs";
import path from "node:path";
import { createServer } from "node:http";
import { EventEmitter } from "node:events";
import { Buffer } from "node:buffer";
import crypto from "node:crypto";
import { Readable, Writable } from "node:stream";
import { Worker } from "node:worker_threads";
import os from "node:os";
import url from "node:url";
import util from "node:util";
import assert from "node:assert";
```

The full list of polyfilled modules:

| Module | Module | Module | Module |
|--------|--------|--------|--------|
| `node:assert` | `node:async_hooks` | `node:buffer` | `node:child_process` |
| `node:cluster` | `node:console` | `node:constants` | `node:crypto` |
| `node:dgram` | `node:diagnostics_channel` | `node:dns` | `node:domain` |
| `node:events` | `node:fs` | `node:http` | `node:http2` |
| `node:https` | `node:inspector` | `node:module` | `node:net` |
| `node:os` | `node:path` | `node:perf_hooks` | `node:process` |
| `node:punycode` | `node:querystring` | `node:readline` | `node:repl` |
| `node:stream` | `node:string_decoder` | `node:sys` | `node:test` |
| `node:timers` | `node:tls` | `node:trace_events` | `node:tty` |
| `node:url` | `node:util` | `node:v8` | `node:vm` |
| `node:wasi` | `node:worker_threads` | `node:zlib` | |

#### Using CommonJS Modules

For npm packages that use `require()`:

```typescript
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);

const legacyLib = require("some-cjs-package");
```

### 4.7 Web APIs

Deno implements standard Web APIs so code is portable between Deno, browsers, and other runtimes:

```typescript
// fetch (WHATWG Fetch API)
const res = await fetch("https://api.github.com/zen");

// Web Crypto
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true,
  ["encrypt", "decrypt"],
);

// Streams
const stream = new ReadableStream({
  start(controller) {
    controller.enqueue("Hello");
    controller.enqueue(" World");
    controller.close();
  },
});

// URL
const url = new URL("/api/users", "https://example.com");

// TextEncoder/TextDecoder
const encoder = new TextEncoder();
const bytes = encoder.encode("Hello Deno");

// WebSocket
const ws = new WebSocket("wss://echo.websocket.org");
ws.onmessage = (e) => console.log(e.data);

// setTimeout, setInterval, queueMicrotask
setTimeout(() => console.log("delayed"), 1000);

// structuredClone
const clone = structuredClone({ nested: { data: [1, 2, 3] } });

// AbortController
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
await fetch("https://slow.api/data", { signal: controller.signal });

// FormData, Headers, Request, Response
const formData = new FormData();
formData.append("file", new Blob(["content"]), "file.txt");

// Performance API
const start = performance.now();
// ... work ...
console.log(`Took ${performance.now() - start}ms`);
```

### 4.8 Deno-Specific APIs

Beyond Web APIs, Deno provides runtime-specific APIs under the `Deno` namespace:

```typescript
// File system
const content = await Deno.readTextFile("data.json");
await Deno.writeTextFile("output.txt", "Hello");
const stat = await Deno.stat("file.ts");
for await (const entry of Deno.readDir("./src")) {
  console.log(entry.name, entry.isFile);
}

// Environment
const home = Deno.env.get("HOME");
Deno.env.set("MY_VAR", "value");

// Subprocess
const command = new Deno.Command("git", {
  args: ["status"],
  stdout: "piped",
});
const { stdout, code } = await command.output();
console.log(new TextDecoder().decode(stdout));

// System info
console.log(Deno.hostname());
console.log(Deno.osRelease());
console.log(Deno.build); // { target, arch, os, vendor, env }

// Signals
Deno.addSignalListener("SIGINT", () => {
  console.log("Interrupted!");
  Deno.exit(0);
});

// Temporary files
const tmpFile = await Deno.makeTempFile({ suffix: ".txt" });

// Network listeners
const listener = Deno.listen({ port: 8080 });
for await (const conn of listener) {
  // handle connection
}
```

### 4.9 HTTP Server with `deno serve`

The `deno serve` command is the built-in way to run HTTP servers:

```typescript
// server.ts
export default {
  fetch(request: Request): Response {
    const url = new URL(request.url);

    if (url.pathname === "/") {
      return new Response("Hello World!");
    }

    if (url.pathname === "/json") {
      return Response.json({ time: new Date().toISOString() });
    }

    return new Response("Not Found", { status: 404 });
  },
};
```

```bash
deno serve --port=8000 server.ts
```

```text
deno serve: Listening on http://0.0.0.0:8000/
```

With parallel workers for production:

```bash
deno serve --parallel --port=8000 server.ts
```

This spawns multiple worker threads to handle requests concurrently using all CPU cores.

> [!TIP]
> `deno serve` automatically handles graceful shutdown on SIGINT/SIGTERM, making it ideal for containerized deployments. You can set the address and port via the `DENO_SERVE_ADDRESS` environment variable instead of CLI flags.

### 4.10 The REPL

Start an interactive TypeScript REPL:

```bash
deno repl
```

```text
Deno 2.7.12
exit using ctrl+d, ctrl+c, or close()
> const x: number = 42;
undefined
> x * 2
84
> await fetch("https://api.github.com/zen").then(r => r.text())
"Anything added dilutes everything else."
>
```

REPL features:
- TypeScript support with type checking
- Top-level `await`
- Tab completion
- Multi-line input (auto-detected)
- `_` holds the last evaluated expression
- `_error` holds the last thrown error
- `.exit` or `Ctrl+D` to quit

Import modules in the REPL:

```text
> import { join } from "jsr:@std/path";
undefined
> join("foo", "bar", "baz")
"foo/bar/baz"
```

Evaluate from a file and drop into REPL:

```bash
deno repl --eval-file=setup.ts
```

---

## 5. Common Tasks

### 5.1 Testing

#### Writing Tests

```typescript
// math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export function divide(a: number, b: number): number {
  if (b === 0) throw new Error("Division by zero");
  return a / b;
}
```

```typescript
// math_test.ts
import { assertEquals, assertThrows } from "@std/assert";
import { add, divide } from "./math.ts";

Deno.test("add - positive numbers", () => {
  assertEquals(add(2, 3), 5);
});

Deno.test("add - negative numbers", () => {
  assertEquals(add(-1, -1), -2);
});

Deno.test("divide - normal division", () => {
  assertEquals(divide(10, 2), 5);
});

Deno.test("divide - throws on zero", () => {
  assertThrows(
    () => divide(1, 0),
    Error,
    "Division by zero",
  );
});
```

```bash
deno test
```

```text
running 4 tests from ./math_test.ts
add - positive numbers ... ok (1ms)
add - negative numbers ... ok (0ms)
divide - normal division ... ok (0ms)
divide - throws on zero ... ok (0ms)

ok | 4 passed | 0 failed (15ms)
```

#### Async Tests

```typescript
Deno.test("fetch returns data", async () => {
  const res = await fetch("https://api.github.com/zen");
  assertEquals(res.status, 200);
  const text = await res.text();
  assert(text.length > 0);
});
```

#### Test Filtering

```bash
# Run tests matching a pattern
deno test --filter "add"

# Run tests in a specific file
deno test math_test.ts

# Run tests in a directory
deno test tests/

# Run only specific test steps
deno test --filter "/divide/"
```

#### Test Steps (Subtests)

```typescript
Deno.test("database operations", async (t) => {
  let db: Database;

  await t.step("connect", async () => {
    db = await Database.connect("sqlite:memory:");
    assert(db);
  });

  await t.step("create table", async () => {
    await db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
  });

  await t.step("insert record", async () => {
    await db.execute("INSERT INTO users (name) VALUES (?)", ["Alice"]);
  });

  await t.step("query record", async () => {
    const rows = await db.query("SELECT name FROM users");
    assertEquals(rows[0].name, "Alice");
  });
});
```

#### Test Permissions

```typescript
Deno.test({
  name: "reads config file",
  permissions: { read: ["./config.json"] },
  fn: async () => {
    const config = await Deno.readTextFile("./config.json");
    assert(config.length > 0);
  },
});
```

#### Parallel Tests

```bash
deno test --parallel
```

This runs test files in parallel across multiple workers. Individual tests within a file still run sequentially unless you use `{ sanitizeOps: false }`.

#### Test Coverage

```bash
# Generate coverage data
deno test --coverage=cov_profile

# View coverage report
deno coverage cov_profile
```

```text
cover math.ts ... 100.000% (12/12)
cover server.ts ... 85.714% (18/21)
```

Generate an HTML report:

```bash
deno coverage cov_profile --html
```

Generate an LCOV report (for CI integration):

```bash
deno coverage cov_profile --lcov --output=coverage.lcov
```

#### Mocking and Spying

```typescript
import { assertSpyCalls, spy, stub } from "@std/testing/mock";
import { FakeTime } from "@std/testing/time";

Deno.test("spy example", () => {
  const log = spy(console, "log");
  console.log("hello");
  assertSpyCalls(log, 1);
  log.restore();
});

Deno.test("stub example", () => {
  const randomStub = stub(Math, "random", () => 0.5);
  assertEquals(Math.random(), 0.5);
  randomStub.restore();
});

Deno.test("fake time", () => {
  using time = new FakeTime();
  const callback = spy();
  setTimeout(callback, 1000);
  time.tick(1000);
  assertSpyCalls(callback, 1);
});
```

#### Snapshot Testing

```typescript
import { assertSnapshot } from "@std/testing/snapshot";

Deno.test("snapshot test", async (t) => {
  const result = generateReport();
  await assertSnapshot(t, result);
});
```

First run creates `__snapshots__/filename.snap`. Subsequent runs compare against it. Update with `--update`:

```bash
deno test --allow-read --allow-write -- --update
```

### 5.2 Formatting

Deno includes a built-in code formatter (based on dprint):

```bash
# Format all files
deno fmt

# Check if files are formatted (CI mode)
deno fmt --check

# Format specific files
deno fmt src/main.ts src/utils.ts

# Format stdin
echo "const   x=1" | deno fmt -
```

```text
Checked 42 files
```

#### Formatter Options

Configure in `deno.json`:

```json
{
  "fmt": {
    "useTabs": false,
    "lineWidth": 80,
    "indentWidth": 2,
    "singleQuote": true,
    "proseWrap": "preserve",
    "semiColons": true,
    "include": ["src/", "tests/"],
    "exclude": ["vendor/", "dist/"]
  }
}
```

| Option | Default | Values |
|--------|---------|--------|
| `useTabs` | `false` | `true`, `false` |
| `lineWidth` | `80` | 1-160 |
| `indentWidth` | `2` | 1-8 |
| `singleQuote` | `false` | `true`, `false` |
| `proseWrap` | `"always"` | `"always"`, `"never"`, `"preserve"` |
| `semiColons` | `true` | `true`, `false` |

Deno also formats Markdown, JSON, and JSONC files by default.

#### Ignoring Formatting

```typescript
// deno-fmt-ignore
const matrix = [
  1, 0, 0,
  0, 1, 0,
  0, 0, 1,
];

// deno-fmt-ignore-file  (at top of file)
```

### 5.3 Linting

```bash
# Lint all files
deno lint

# Lint specific files
deno lint src/main.ts

# Output as JSON
deno lint --json
```

```text
Checked 42 files
(no output means no errors)
```

When issues are found:

```text
error[no-unused-vars]: `helper` is never used
 --> src/main.ts:3:7
  |
3 | const helper = () => {};
  |       ^^^^^^
  = hint: If this is intentional, prefix it with an underscore like `_helper`

Found 1 problem
```

#### Lint Rules

Configure in `deno.json`:

```json
{
  "lint": {
    "include": ["src/"],
    "exclude": ["src/generated/"],
    "rules": {
      "tags": ["recommended"],
      "include": [
        "ban-untagged-todo",
        "no-unused-vars",
        "explicit-function-return-type",
        "no-await-in-loop"
      ],
      "exclude": ["no-explicit-any"]
    }
  }
}
```

Available rule tags: `recommended`, `fresh` (stricter set for new projects).

#### Ignoring Lint Rules

```typescript
// deno-lint-ignore no-explicit-any
const data: any = JSON.parse(input);

// deno-lint-ignore-file no-explicit-any
// (at top of file — ignores for entire file)

// deno-lint-ignore no-unused-vars no-explicit-any
// (multiple rules on one line)
```

### 5.4 Type Checking

```bash
# Type-check a file and its dependencies
deno check main.ts

# Type-check all files in the project
deno check **/*.ts

# Type-check with remote modules
deno check --remote main.ts
```

```text
Check file:///home/user/project/main.ts
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
    add("hello", 5);
        ~~~~~~~
    at file:///home/user/project/main.ts:8:9
```

> [!NOTE]
> `deno run` does NOT type-check by default (for fast startup). Use `deno check` explicitly in your CI pipeline, or pass `--check` to `deno run` if you want type checking before execution: `deno run --check main.ts`.

### 5.5 Dependency Management

#### Adding Dependencies

```bash
# Add from JSR
deno add jsr:@std/http
deno add jsr:@oak/oak

# Add from npm
deno add npm:express
deno add npm:zod

# Add multiple at once
deno add jsr:@std/path jsr:@std/assert npm:chalk
```

This updates `deno.json`:

```json
{
  "imports": {
    "@oak/oak": "jsr:@oak/oak@^17.1.4",
    "@std/assert": "jsr:@std/assert@^1.0.12",
    "@std/http": "jsr:@std/http@^1.0.16",
    "@std/path": "jsr:@std/path@^1.0.10",
    "chalk": "npm:chalk@^5.4.1",
    "express": "npm:express@^4.21.2",
    "zod": "npm:zod@^3.24.2"
  }
}
```

#### Removing Dependencies

```bash
deno remove express
deno remove @std/http
```

#### Installing Dependencies (Cache Warming)

```bash
# Cache all dependencies referenced in deno.json
deno install

# Cache dependencies for a specific entry point
deno cache main.ts

# Force re-download
deno cache --reload main.ts

# Reload specific packages
deno cache --reload=jsr:@std/http main.ts
```

#### Viewing Dependency Info

```bash
deno info main.ts
```

```text
local: /home/user/project/main.ts
type: TypeScript
emit: /home/user/.cache/deno/gen/file/home/user/project/main.ts.js
dependencies: 7 unique
size: 125.4KB

file:///home/user/project/main.ts (1.2KB)
├── jsr:@std/http@1.0.16/serve (15.3KB)
│   ├── jsr:@std/http@1.0.16/_negotiation (2.1KB)
│   └── jsr:@std/http@1.0.16/status (0.8KB)
└── file:///home/user/project/utils.ts (0.5KB)
```

#### Auditing Dependencies

```bash
deno audit
```

This checks your dependency tree against known vulnerability databases.

#### Checking for Outdated Dependencies

```bash
deno outdated
```

```text
Package          Current  Latest
@std/http        1.0.14   1.0.16
npm:express      4.18.2   4.21.2
npm:zod          3.22.4   3.24.2
```

Update all dependencies:

```bash
deno outdated --update
```

### 5.6 Benchmarking

```typescript
// bench_example.ts
Deno.bench("URL parsing", () => {
  new URL("https://example.com/path?query=1#hash");
});

Deno.bench("JSON parse small", () => {
  JSON.parse('{"name":"deno","version":"2.7.12"}');
});

Deno.bench("JSON parse large", () => {
  JSON.parse(JSON.stringify(Array.from({ length: 1000 }, (_, i) => i)));
});

Deno.bench({
  name: "async file read",
  permissions: { read: true },
  fn: async () => {
    await Deno.readTextFile("bench_example.ts");
  },
});
```

```bash
deno bench
```

```text
cpu: AMD Ryzen 9 7950X
runtime: deno 2.7.12 (x86_64-unknown-linux-gnu)

bench_example.ts
benchmark              time/iter (avg)        iter/s      (min … max)
---------------------- ------------------- ------------ -----------------
URL parsing                   148.32 ns    6,742,000.0 (142.11 ns … 1.23 µs)
JSON parse small               89.44 ns   11,180,000.0 ( 85.12 ns … 342.1 ns)
JSON parse large               12.15 µs       82,300.0 ( 11.22 µs … 45.3 µs)
async file read                 4.22 µs      237,000.0 (  3.81 µs … 12.1 µs)
```

Filter benchmarks:

```bash
deno bench --filter "JSON"
```

### 5.7 Documentation Generation

Generate documentation for your modules:

```bash
# View docs in terminal
deno doc mod.ts

# Generate HTML docs
deno doc --html --output=docs mod.ts

# View docs for a remote module
deno doc jsr:@std/http/serve

# Generate JSON output
deno doc --json mod.ts
```

Write JSDoc comments for your exports:

```typescript
/**
 * Calculates the factorial of a non-negative integer.
 *
 * @param n - The non-negative integer
 * @returns The factorial of n
 * @throws {RangeError} If n is negative
 *
 * @example
 * ```ts
 * import { factorial } from "./math.ts";
 * factorial(5); // 120
 * ```
 */
export function factorial(n: number): number {
  if (n < 0) throw new RangeError("n must be non-negative");
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
```

### 5.8 Compiling to Standalone Binaries

```bash
# Compile for current platform
deno compile --output=myapp main.ts

# Compile with permissions baked in
deno compile --allow-net --allow-read --output=myapp main.ts

# Cross-compile for different targets
deno compile --target=x86_64-unknown-linux-gnu --output=myapp-linux main.ts
deno compile --target=aarch64-apple-darwin --output=myapp-mac main.ts
deno compile --target=x86_64-pc-windows-msvc --output=myapp.exe main.ts

# Include static files
deno compile --include=static/ --include=templates/ --output=myapp main.ts
```

```text
Compile file:///home/user/project/main.ts to myapp
```

Available compilation targets:

| Target | OS | Arch |
|--------|-----|------|
| `x86_64-unknown-linux-gnu` | Linux | x86_64 |
| `aarch64-unknown-linux-gnu` | Linux | ARM64 |
| `x86_64-pc-windows-msvc` | Windows | x86_64 |
| `x86_64-apple-darwin` | macOS | Intel |
| `aarch64-apple-darwin` | macOS | Apple Silicon |

The compiled binary includes the Deno runtime, your code, and all dependencies in a single executable. No Deno installation needed to run it.

> [!CAUTION]
> Known issue in Deno 2.7.5+ (issue [#32821](https://github.com/denoland/deno/issues/32821)): compiled binaries may hang on startup. If you encounter this, compile with Deno 2.7.4 as a workaround until the fix lands.

### 5.9 Publishing to JSR

The JavaScript Registry (JSR) is the native package registry for Deno.

#### Prepare Your Package

```jsonc
// deno.json
{
  "name": "@myorg/mylib",
  "version": "1.0.0",
  "exports": {
    ".": "./mod.ts",
    "./utils": "./utils.ts"
  },
  "publish": {
    "include": ["src/", "mod.ts", "README.md", "LICENSE"],
    "exclude": ["tests/", "bench/"]
  }
}
```

#### Publish

```bash
# Dry run first
deno publish --dry-run

# Publish
deno publish
```

```text
Publishing @myorg/mylib@1.0.0 ...
Successfully published @myorg/mylib@1.0.0
```

#### Version Management

JSR enforces semantic versioning. Increment the `version` in `deno.json` before each publish.

### 5.10 Deploying to Deno Deploy

```bash
# Deploy the current project
deno deploy

# Deploy with a specific entry point
deno deploy --entrypoint=main.ts

# Set the project name
deno deploy --project=my-app

# Deploy with environment variables
DENO_DEPLOY_TOKEN=your_token deno deploy --project=my-app
```

Set the deploy token via environment variable:

```bash
export DENO_DEPLOY_TOKEN="ddp_xxxxxxxxxxxxxxxxxxxx"
```

### 5.11 Working with JSON

```typescript
// Read JSON
const config = JSON.parse(await Deno.readTextFile("config.json"));

// Write JSON (formatted)
await Deno.writeTextFile(
  "output.json",
  JSON.stringify(data, null, 2),
);

// JSON imports (with assertion)
import config from "./config.json" with { type: "json" };
console.log(config.database.host);
```

### 5.12 Working with Streams

```typescript
// Read a file as a stream
const file = await Deno.open("large_file.txt");
const reader = file.readable.getReader();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(`Read ${value.byteLength} bytes`);
}

// Pipe a download to a file
const response = await fetch("https://example.com/large-file.zip");
const outputFile = await Deno.open("download.zip", { write: true, create: true });
await response.body!.pipeTo(outputFile.writable);

// Transform streams
const textStream = new ReadableStream({
  start(controller) {
    controller.enqueue("hello world");
    controller.close();
  },
}).pipeThrough(new TextEncoderStream());
```

### 5.13 Subprocess Management

```typescript
// Simple command
const command = new Deno.Command("echo", {
  args: ["Hello from subprocess"],
});
const { code, stdout, stderr } = await command.output();
console.log(new TextDecoder().decode(stdout)); // "Hello from subprocess\n"

// Streaming output
const process = new Deno.Command("ping", {
  args: ["-c", "3", "google.com"],
  stdout: "piped",
}).spawn();

for await (const chunk of process.stdout) {
  console.log(new TextDecoder().decode(chunk));
}
const status = await process.status;

// Piping between processes
const lsCmd = new Deno.Command("ls", {
  args: ["-la"],
  stdout: "piped",
});
const grepCmd = new Deno.Command("grep", {
  args: [".ts"],
  stdin: "piped",
  stdout: "piped",
});

const ls = lsCmd.spawn();
const grep = grepCmd.spawn();

ls.stdout.pipeTo(grep.stdin);
const result = await grep.output();
console.log(new TextDecoder().decode(result.stdout));
```

### 5.14 Workers (Multi-Threading)

```typescript
// main.ts
const worker = new Worker(
  new URL("./worker.ts", import.meta.url).href,
  { type: "module" },
);

worker.postMessage({ numbers: [1, 2, 3, 4, 5] });

worker.onmessage = (event) => {
  console.log("Sum:", event.data.sum); // Sum: 15
  worker.terminate();
};
```

```typescript
// worker.ts
self.onmessage = (event) => {
  const { numbers } = event.data;
  const sum = numbers.reduce((a: number, b: number) => a + b, 0);
  self.postMessage({ sum });
};
```

### 5.15 Foreign Function Interface (FFI)

Call native libraries from Deno:

```typescript
const lib = Deno.dlopen("libm.so.6", {
  cos: { parameters: ["f64"], result: "f64" },
  sin: { parameters: ["f64"], result: "f64" },
});

console.log(lib.symbols.cos(0));  // 1.0
console.log(lib.symbols.sin(0));  // 0.0

lib.close();
```

```bash
deno run --allow-ffi --unstable-ffi main.ts
```

### 5.16 WebSocket Server

```typescript
// ws_server.ts
Deno.serve({ port: 8080 }, (request) => {
  if (request.headers.get("upgrade") !== "websocket") {
    return new Response("Expected WebSocket", { status: 400 });
  }

  const { socket, response } = Deno.upgradeWebSocket(request);

  socket.onopen = () => console.log("Client connected");
  socket.onmessage = (event) => {
    console.log("Received:", event.data);
    socket.send(`Echo: ${event.data}`);
  };
  socket.onclose = () => console.log("Client disconnected");

  return response;
});

console.log("WebSocket server running on ws://localhost:8080");
```

```bash
deno run --allow-net ws_server.ts
```

### 5.17 File Server (One-Liner)

Serve the current directory as static files:

```bash
deno run --allow-net --allow-read jsr:@std/http/file-server
```

```text
Listening on http://0.0.0.0:4507/
```

With options:

```bash
deno run --allow-net --allow-read jsr:@std/http/file-server --port=3000 --dir-listing
```

### 5.18 Cron / Scheduled Tasks (Unstable)

```typescript
// Enable in deno.json: "unstable": ["cron"]

Deno.cron("daily-report", "0 9 * * *", async () => {
  console.log("Generating daily report...");
  await generateReport();
});

Deno.cron("cleanup", "*/5 * * * *", async () => {
  console.log("Running cleanup every 5 minutes");
  await cleanup();
});
```

### 5.19 Deno KV (Key-Value Store, Unstable)

```typescript
// Enable in deno.json: "unstable": ["kv"]

const kv = await Deno.openKv();

// Set a value
await kv.set(["users", "alice"], { name: "Alice", age: 30 });

// Get a value
const result = await kv.get(["users", "alice"]);
console.log(result.value); // { name: "Alice", age: 30 }

// List entries by prefix
const entries = kv.list({ prefix: ["users"] });
for await (const entry of entries) {
  console.log(entry.key, entry.value);
}

// Atomic transactions
const res = await kv.atomic()
  .check({ key: ["users", "alice"], versionstamp: result.versionstamp })
  .set(["users", "alice"], { name: "Alice", age: 31 })
  .commit();

if (res.ok) {
  console.log("Updated successfully");
}

// Delete
await kv.delete(["users", "alice"]);

kv.close();
```

### 5.20 Jupyter Notebook Integration

Deno can serve as a Jupyter kernel:

```bash
deno jupyter --install
```

```text
✅ Deno kernel successfully registered
```

Then create a new notebook in JupyterLab and select the "Deno" kernel. You get full TypeScript support, top-level await, and access to all Deno APIs in notebook cells.

### 5.21 Building a REST API (Full Example)

```typescript
// api.ts
interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

const todos: Todo[] = [
  { id: 1, title: "Learn Deno", completed: true },
  { id: 2, title: "Build an API", completed: false },
];

let nextId = 3;

function jsonResponse(data: unknown, status = 200): Response {
  return new Response(JSON.stringify(data), {
    status,
    headers: { "Content-Type": "application/json" },
  });
}

export default {
  fetch(request: Request): Response {
    const url = new URL(request.url);
    const path = url.pathname;

    // GET /todos
    if (request.method === "GET" && path === "/todos") {
      return jsonResponse(todos);
    }

    // GET /todos/:id
    const match = path.match(/^\/todos\/(\d+)$/);
    if (request.method === "GET" && match) {
      const todo = todos.find((t) => t.id === Number(match[1]));
      if (!todo) return jsonResponse({ error: "Not found" }, 404);
      return jsonResponse(todo);
    }

    // POST /todos
    if (request.method === "POST" && path === "/todos") {
      return (async () => {
        const body = await request.json();
        const todo: Todo = {
          id: nextId++,
          title: body.title,
          completed: false,
        };
        todos.push(todo);
        return jsonResponse(todo, 201);
      })();
    }

    return jsonResponse({ error: "Not found" }, 404);
  },
};
```

```bash
deno serve --port=8000 api.ts
```

Test it:

```bash
# List todos
curl http://localhost:8000/todos

# Get one todo
curl http://localhost:8000/todos/1

# Create a todo
curl -X POST http://localhost:8000/todos -H "Content-Type: application/json" -d '{"title":"Deploy to production"}'
```

### 5.22 Database Access

#### SQLite

```typescript
const db = new Deno.openKv(":memory:"); // KV as embedded store
// Or use the community SQLite driver:
import { DB } from "https://deno.land/x/sqlite/mod.ts";

const db = new DB("app.db");
db.execute(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE
  )
`);

db.query("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "[email removed]"]);

for (const [id, name, email] of db.query("SELECT * FROM users")) {
  console.log(id, name, email);
}

db.close();
```

#### PostgreSQL

```typescript
import postgres from "npm:postgres@^3";

const sql = postgres("postgresql://user:pass@localhost:5432/mydb");

const users = await sql`SELECT * FROM users WHERE active = ${true}`;
console.log(users);

await sql.end();
```

### 5.23 Environment Variables

```typescript
// Read
const dbUrl = Deno.env.get("DATABASE_URL");
if (!dbUrl) {
  console.error("DATABASE_URL is required");
  Deno.exit(1);
}

// Set (within the process)
Deno.env.set("NODE_ENV", "production");

// List all
for (const [key, value] of Object.entries(Deno.env.toObject())) {
  console.log(`${key}=${value}`);
}
```

Load `.env` files:

```typescript
import "@std/dotenv/load";
// or
import { load } from "@std/dotenv";
const env = await load();
```

```bash
deno run --allow-env --allow-read main.ts
```

### 5.24 Signals and Graceful Shutdown

```typescript
const server = Deno.serve({ port: 8000 }, (_req) => {
  return new Response("Hello");
});

// Handle SIGINT (Ctrl+C)
Deno.addSignalListener("SIGINT", () => {
  console.log("\nGracefully shutting down...");
  server.shutdown();
});

// Handle SIGTERM (from container orchestrators)
Deno.addSignalListener("SIGTERM", () => {
  console.log("SIGTERM received, shutting down...");
  server.shutdown();
});

console.log("Server running on http://localhost:8000");
await server.finished;
console.log("Server shut down cleanly.");
```

### 5.25 OpenTelemetry Integration

Deno has built-in OpenTelemetry support for traces and metrics:

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
OTEL_SERVICE_NAME=my-deno-app \
deno run --allow-net --allow-env --unstable-otel main.ts
```

Traces from `fetch()`, `Deno.serve()`, and other built-in APIs are emitted automatically when OTEL is configured.

### 5.26 Building a CLI Tool

```typescript
// cli.ts
import { parseArgs } from "jsr:@std/cli/parse-args";

const args = parseArgs(Deno.args, {
  string: ["name", "output"],
  boolean: ["verbose", "help"],
  alias: { n: "name", o: "output", v: "verbose", h: "help" },
  default: { verbose: false },
});

if (args.help) {
  console.log(`
Usage: greet [options]

Options:
  -n, --name <name>    Name to greet
  -o, --output <file>  Output file
  -v, --verbose        Verbose output
  -h, --help           Show help
`);
  Deno.exit(0);
}

const greeting = `Hello, ${args.name ?? "World"}!`;

if (args.verbose) {
  console.log(`Generating greeting for: ${args.name}`);
}

if (args.output) {
  await Deno.writeTextFile(args.output, greeting);
  console.log(`Written to ${args.output}`);
} else {
  console.log(greeting);
}
```

Install globally:

```bash
deno install --global --allow-read --allow-write -n greet cli.ts
greet --name "Deno User"
```

```text
Hello, Deno User!
```

### 5.27 Testing HTTP Handlers

```typescript
// handler.ts
export function handler(request: Request): Response {
  const url = new URL(request.url);
  if (url.pathname === "/health") {
    return new Response("OK", { status: 200 });
  }
  return new Response("Not Found", { status: 404 });
}
```

```typescript
// handler_test.ts
import { assertEquals } from "@std/assert";
import { handler } from "./handler.ts";

Deno.test("health check returns 200", async () => {
  const req = new Request("http://localhost/health");
  const res = handler(req);
  assertEquals(res.status, 200);
  assertEquals(await res.text(), "OK");
});

Deno.test("unknown route returns 404", async () => {
  const req = new Request("http://localhost/unknown");
  const res = handler(req);
  assertEquals(res.status, 404);
});
```

### 5.28 Bundling

```bash
deno bundle main.ts output.js
```

> [!NOTE]
> `deno bundle` is considered legacy. For production builds, prefer `deno compile` for standalone binaries or use a build tool like esbuild (`npm:esbuild`) for web bundles. The bundler may be removed in a future version.

### 5.29 Vendoring Dependencies

Download all remote dependencies into a local `vendor/` directory:

```bash
deno vendor main.ts
```

This creates a `vendor/` directory with all remote modules and an import map. Useful for:
- Air-gapped environments
- Auditing dependencies
- Checking dependencies into version control

### 5.30 Global Installs and Uninstalls

```bash
# Install a script globally
deno install --global --allow-net -n serve jsr:@std/http/file-server

# List global installs
ls ~/.deno/bin/

# Uninstall
deno uninstall --global serve
```

### 5.31 LSP (Language Server Protocol)

Deno ships a built-in LSP for editor integration:

```bash
deno lsp
```

#### VS Code Setup

Install the official "Deno" extension (`denoland.vscode-deno`). Enable it in `.vscode/settings.json`:

```json
{
  "deno.enable": true,
  "deno.lint": true,
  "deno.unstable": ["kv"],
  "editor.defaultFormatter": "denoland.vscode-deno",
  "[typescript]": {
    "editor.defaultFormatter": "denoland.vscode-deno"
  }
}
```

Features: auto-completion, go-to-definition, hover types, inline diagnostics, code actions, formatting, import suggestions, test code lens.

> [!WARNING]
> Known issue ([#33289](https://github.com/denoland/deno/issues/33289)): the LSP may not recognize globally declared types (ambient declarations) unless the declaring file is currently open in the editor. Workaround: add the declaration file to a `/// <reference path="..." />` directive in the affected file.

### 5.32 Printing TypeScript Declarations

```bash
deno types
```

Outputs the built-in TypeScript declaration file for all Deno APIs. Pipe it to a file for offline reference:

```bash
deno types > deno.d.ts
```

---

## 6. Troubleshooting

### 6.1 Permission Errors

### Error: `Requires read access to "/path/to/file", run again with the --allow-read flag`

**Cause:** Your script tried to read a file but you did not grant `--allow-read`.

**Solution:**

```bash
# Allow reading a specific path
deno run --allow-read=/path/to/file main.ts

# Allow reading the current directory and below
deno run --allow-read=. main.ts
```

**Prevention:** Plan your permission flags before running. Use `deno task` entries with permissions pre-configured so you do not have to remember them.

---

### Error: `Requires net access to "api.example.com:443", run again with the --allow-net flag`

**Cause:** Your script made a network request without the `--allow-net` permission.

**Solution:**

```bash
deno run --allow-net=api.example.com main.ts
```

**Prevention:** Scope network permissions to specific hosts in production: `--allow-net=api.example.com,db.example.com`.

---

### Error: `Requires env access to "DATABASE_URL", run again with the --allow-env flag`

**Cause:** Your script tried to read an environment variable without `--allow-env`.

**Solution:**

```bash
deno run --allow-env=DATABASE_URL main.ts
```

---

### Error: `Requires run access to "git", run again with the --allow-run flag`

**Cause:** Your script tried to spawn a subprocess without `--allow-run`.

**Solution:**

```bash
deno run --allow-run=git main.ts
```

> [!CAUTION]
> Be very careful with `--allow-run` without a subprocess allow-list. An unrestricted `--allow-run` lets the script execute any program on the system, effectively bypassing all other permissions.

### 6.2 Module Resolution Errors

### Error: `Module not found "file:///path/to/module.ts"`

**Cause:** The imported file does not exist at the specified path or you forgot the file extension.

**Solution:** Deno requires explicit file extensions for local imports:

```typescript
// Wrong
import { foo } from "./module";

// Correct
import { foo } from "./module.ts";
```

---

### Error: `error: Uncaught TypeError: Cannot find package 'some-package'`

**Cause:** You imported an npm package without the `npm:` prefix.

**Solution:**

```typescript
// Wrong
import express from "express";

// Correct (direct import)
import express from "npm:express";

// Correct (via import map in deno.json)
// deno.json: { "imports": { "express": "npm:express@^4" } }
import express from "express";
```

---

### Error: `The source code is invalid, as it does not match the expected hash in the lock file`

**Cause:** A remote dependency changed since the lock file was generated.

**Solution:**

```bash
# Verify the change is expected, then update the lock file
deno cache --lock=deno.lock --lock-write main.ts
```

> [!WARNING]
> Investigate why the hash changed before updating. A hash mismatch could indicate a supply-chain attack. Compare the old and new versions of the module before accepting the change.

---

### Error: `error: Unsupported scheme "node"` or `error: Module not found "node:fs"`

**Cause:** This typically happens on very old Deno versions (pre-1.x). On Deno 2.x, `node:` imports work out of the box.

**Solution:** Upgrade Deno:

```bash
deno upgrade
```

### 6.3 TypeScript Errors

### Error: `TS2307 [ERROR]: Cannot find module '@std/path' or its corresponding type declarations`

**Cause:** The import is not in your `deno.json` imports map, or the package is not cached.

**Solution:**

```bash
deno add jsr:@std/path
deno cache main.ts
```

---

### Error: `TS2345 [ERROR]: Argument of type 'X' is not assignable to parameter of type 'Y'`

**Cause:** Type mismatch in your code. Deno uses `strict: true` by default.

**Solution:** Fix the type error in your code, or if you need to bypass temporarily:

```typescript
// @ts-ignore: reason for ignoring
someFunction(value as any);
```

---

### Error: `TS2304 [ERROR]: Cannot find name 'Deno'`

**Cause:** The `lib` compiler option does not include Deno's type declarations.

**Solution:** In `deno.json`:

```json
{
  "compilerOptions": {
    "lib": ["deno.window"]
  }
}
```

### 6.4 Network and TLS Errors

### Error: `error: error sending request [...] tls handshake eof`

**Cause:** TLS negotiation failed, often due to self-signed certificates or corporate proxies.

**Solution:**

```bash
# Use a custom CA cert
deno run --cert=./ca-cert.pem --allow-net main.ts

# Or set via environment variable
DENO_CERT=/path/to/cert.pem deno run --allow-net main.ts
```

---

### Error: TLS connection to Postgres via `npm:pg@8` times out

**Cause:** Known issue ([#33296](https://github.com/denoland/deno/issues/33296)). TLS connections via the `pg` npm package can time out in Deno 2.7.x.

**Solution:** Try `npm:postgres` (the pure-JS client) as an alternative:

```typescript
import postgres from "npm:postgres";
const sql = postgres("postgres://user:pass@host/db");
```

---

### Error: `error: error sending request [...] connection refused`

**Cause:** The target server is not running or is blocked by firewall.

**Solution:** Verify the server is running and reachable:

```bash
curl -v http://localhost:8000
```

If using Docker, ensure the container port is mapped and the service is bound to `0.0.0.0`, not `127.0.0.1`.

### 6.5 Runtime Errors

### Error: `error: Top-level await is not allowed in the current context`

**Cause:** This happens when using top-level `await` in a script that Deno treats as a classic script.

**Solution:** Ensure your file has a `.ts`, `.mts`, `.js`, or `.mjs` extension. Deno treats these as ES modules automatically.

---

### Error: `Uncaught PermissionDenied: [...] not in the allow list`

**Cause:** You provided a scoped permission but the code is accessing something outside the scope.

**Solution:** Widen the permission scope or add the missing path/host:

```bash
# Before (too narrow)
deno run --allow-read=./src main.ts

# After (include config directory too)
deno run --allow-read=./src,./config main.ts
```

---

### Error: `error: Worker terminated`

**Cause:** A Web Worker crashed or was terminated unexpectedly.

**Solution:** Wrap worker code in try/catch and check for errors:

```typescript
worker.onerror = (event) => {
  console.error("Worker error:", event.message);
};
```

---

### Error: `Panic: [...] assertion failed`

**Cause:** An internal Deno bug. Panics are Rust-level crashes.

**Solution:** Report the issue at [github.com/denoland/deno/issues](https://github.com/denoland/deno/issues) with the full panic trace. Check if a newer version includes a fix:

```bash
deno upgrade
```

Known panic: running `Task fmt prettier --write . && deno fmt` can trigger a panic ([#33302](https://github.com/denoland/deno/issues/33302)). Run prettier and `deno fmt` as separate tasks instead.

> [!CAUTION]
> If you encounter a panic consistently, check the [Deno issues page](https://github.com/denoland/deno/issues) for existing reports before filing a new one. Include your OS, Deno version (`deno --version`), and the minimal reproduction steps.

### 6.6 Compilation Issues

### Error: Compiled binary hangs on startup

**Cause:** Known regression in Deno 2.7.5+ ([#32821](https://github.com/denoland/deno/issues/32821)).

**Solution:** Downgrade to Deno 2.7.4 for compilation:

```bash
deno upgrade --version 2.7.4
deno compile --output=myapp main.ts
deno upgrade  # Go back to latest for development
```

---

### Error: `error: Could not find constraint in the list of versions`

**Cause:** A dependency version constraint cannot be satisfied.

**Solution:** Check for typos in your version specifier and ensure the package exists:

```bash
deno info npm:package-name
```

### 6.7 Formatter and Linter Issues

### Error: `error: Failed to format` or formatter produces unexpected output

**Cause:** A syntax error in the file or unsupported language construct.

**Solution:** Fix the syntax error first. Run `deno check` to find errors, then format.

---

### Error: `Not implemented: [feature]` from lint rules

**Cause:** Some lint rules are not fully implemented for all code patterns.

**Solution:** Disable the specific rule for that line:

```typescript
// deno-lint-ignore rule-name
```

### 6.8 Performance Issues

### Problem: Slow startup time

**Cause:** Large dependency trees or uncached remote modules.

**Solution:**

```bash
# Pre-cache all dependencies
deno cache main.ts

# Skip type checking for faster startup
deno run main.ts  # (no --check flag)
```

---

### Problem: High memory usage

**Cause:** V8's default heap limit or large data processing.

**Solution:** Increase V8's heap:

```bash
DENO_V8_FLAGS="--max-old-space-size=8192" deno run main.ts
```

---

### Problem: Tests run slowly

**Cause:** Tests running sequentially, or each test doing expensive setup.

**Solution:**

```bash
# Run test files in parallel
deno test --parallel

# Set parallel job count
DENO_JOBS=8 deno test --parallel
```

### 6.9 Platform-Specific Issues

### Error: `node:fs writeFileSync throws EEXIST when overwriting` (Windows)

**Cause:** Known Windows-specific issue ([#33254](https://github.com/denoland/deno/issues/33254)) where `writeFileSync` throws `EEXIST` instead of overwriting.

**Solution:** Use the async `writeFile` or add `{ flag: "w" }`:

```typescript
// Workaround
import { writeFileSync } from "node:fs";
try {
  writeFileSync(path, data);
} catch (e) {
  if (e.code === "EEXIST") {
    // Delete and retry on Windows
    Deno.removeSync(path);
    writeFileSync(path, data);
  }
}

// Better: use Deno's native API
await Deno.writeTextFile(path, data);
```

---

### Error: Firefox launch with Playwright times out

**Cause:** Known issue ([#33229](https://github.com/denoland/deno/issues/33229)) with Playwright's Firefox launcher in Deno.

**Solution:** Use Chromium with Playwright instead:

```typescript
import { chromium } from "npm:playwright";
const browser = await chromium.launch();
```

---

### Error: `crypto.verify` throws Invalid PEM error

**Cause:** Known issue ([#33291](https://github.com/denoland/deno/issues/33291)) with certain PEM-encoded keys.

**Solution:** Ensure the PEM key has proper line breaks and headers. As a workaround, import the key as raw bytes:

```typescript
const keyData = await Deno.readFile("key.der");
const key = await crypto.subtle.importKey(
  "pkcs8",
  keyData,
  { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
  false,
  ["sign"],
);
```

### 6.10 Cache Issues

### Problem: Stale cached modules

**Cause:** Deno caches remote modules aggressively.

**Solution:**

```bash
# Reload all remote modules
deno cache --reload main.ts

# Reload specific modules
deno cache --reload=https://deno.land main.ts
deno cache --reload=npm:express main.ts
```

---

### Problem: Cache directory growing too large

**Cause:** Accumulated cached modules over time.

**Solution:** Clear the cache:

```bash
# Find your cache directory
deno info

# The "DENO_DIR" line shows the cache location
# Clear it manually
rm -rf ~/.cache/deno  # Linux
rm -rf ~/Library/Caches/deno  # macOS
```

Or set a custom cache directory:

```bash
export DENO_DIR=/tmp/deno-cache
```

### 6.11 Source Map Issues

### Error: Inline source maps from TypeScript not applied

**Cause:** Known issue ([#32355](https://github.com/denoland/deno/issues/32355)) where inline source maps in transformed TypeScript are not properly applied.

**Solution:** Use external source map files or rely on Deno's built-in TypeScript support (which does not require source maps for `.ts` files).

### 6.12 Test Runner Issues

### Error: Test Explorer environment file loading diverges from CLI

**Cause:** Known issue ([#33284](https://github.com/denoland/deno/issues/33284)). The VS Code Test Explorer loads `.env` files differently than the CLI test runner.

**Solution:** Pass environment variables explicitly or use `@std/dotenv/load` in a test setup file rather than relying on automatic `.env` loading.

---

### Error: `no output recorded` in VS Code test run

**Cause:** Known issue ([#28797](https://github.com/denoland/deno/issues/28797)) with the VS Code Deno extension test integration.

**Solution:** Run tests from the terminal instead:

```bash
deno test --allow-read
```

> [!WARNING]
> When switching between the VS Code Test Explorer and CLI test execution, be aware that permission handling, environment variable loading, and output capture may differ. The CLI runner (`deno test`) is the authoritative test runner.

---

## 7. FAQ

### General

**Q: What is the difference between Deno and Node.js?**
A: Deno is secure by default (sandboxed), supports TypeScript natively (no build step), uses ES modules exclusively (no CommonJS), includes a complete toolchain (formatter, linter, test runner), and has built-in Web API compatibility. Node.js has a larger ecosystem and longer track record.

**Q: Can I use my existing Node.js code in Deno?**
A: Most Node.js code works with minimal changes. Use `node:` prefixed imports for built-in modules (`import fs from "node:fs"`) and `npm:` specifiers for packages (`import express from "npm:express"`). CommonJS `require()` is available via `createRequire()` from `node:module`.

**Q: Is Deno production-ready?**
A: Yes. Deno 2.x is a stable release with SemVer guarantees. Companies including Netlify, Slack, and GitHub use Deno in production. The stable APIs (non-`unstable` flagged) follow backward-compatibility rules.

**Q: What license is Deno?**
A: MIT license.

**Q: How large is the Deno binary?**
A: Approximately 80-130 MB depending on the platform. It bundles V8, the TypeScript compiler, and the full toolchain.

**Q: Does Deno support Windows?**
A: Yes. Deno supports Windows 10+ on x86_64. Some features have platform-specific behaviors (see the Windows-specific issues in the Troubleshooting section).

### TypeScript

**Q: Do I need to install TypeScript separately?**
A: No. Deno includes the TypeScript compiler. Just write `.ts` files and run them directly.

**Q: What TypeScript version does Deno 2.7.12 use?**
A: TypeScript 5.7.3.

**Q: Can I use a `tsconfig.json`?**
A: Not directly. Deno uses the `compilerOptions` field in `deno.json`. Most `tsconfig.json` options have equivalents.

**Q: Does Deno type-check when I run `deno run`?**
A: No. `deno run` skips type checking for faster startup. Use `deno check` for type checking, or `deno run --check` to check before running.

**Q: How do I use JSX/TSX?**
A: Add JSX configuration to `deno.json`:

```json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react"
  }
}
```

### Modules and Dependencies

**Q: Where does Deno cache modules?**
A: In `$DENO_DIR` (defaults to `~/.cache/deno` on Linux, `~/Library/Caches/deno` on macOS, `%LOCALAPPDATA%\deno` on Windows). Run `deno info` to see the exact path.

**Q: How do I use private npm packages?**
A: Deno reads `.npmrc` for registry configuration, including authentication tokens for private registries.

**Q: What is JSR and how does it differ from npm?**
A: JSR (JavaScript Registry) is a new package registry designed for Deno and modern runtimes. It natively supports TypeScript, ES modules, and semantic versioning. npm packages work in Deno via the `npm:` specifier, but JSR packages are optimized for Deno's module system.

**Q: Can I use import maps?**
A: Yes. The `"imports"` field in `deno.json` IS the import map. Deno also supports standalone import map files with `--import-map=import_map.json`.

**Q: How do I pin dependency versions?**
A: Use `deno.lock` (generated automatically) for hash-level pinning. Use exact versions in your import map for version pinning: `"@std/http": "jsr:@std/http@1.0.16"` (no `^` or `~`).

**Q: What is the `vendor/` directory for?**
A: Running `deno vendor main.ts` downloads all remote dependencies into `vendor/`. Useful for air-gapped environments, auditing, or checking dependencies into version control.

### Permissions and Security

**Q: Why does Deno need permission flags?**
A: Security. Deno sandboxes all scripts by default. No file, network, environment, or subprocess access unless explicitly granted. This prevents malicious or buggy code from harming your system.

**Q: Can a dependency request permissions that my main script does not have?**
A: No. Permissions are granted at the process level. If you run `deno run --allow-net=api.github.com main.ts`, then all code in the process (including dependencies) can only access `api.github.com`. No dependency can escalate beyond what you granted.

**Q: What does `-A` / `--allow-all` do exactly?**
A: It grants all permissions: read, write, net, env, run, sys, ffi. The sandbox is effectively disabled. Use only for trusted code during development.

**Q: Can deny flags override `--allow-all`?**
A: No. `--allow-all` takes absolute precedence. Deny flags only work when used alongside specific allow flags.

### Configuration

**Q: Is `deno.json` required?**
A: No. Deno works without any configuration file. All defaults are sensible. The config file is for customizing behavior, defining tasks, and setting up import maps.

**Q: Can I use `deno.jsonc` instead of `deno.json`?**
A: Yes. Deno supports both. The `.jsonc` extension allows comments and trailing commas.

**Q: How do I enable unstable APIs?**
A: In `deno.json`:

```json
{
  "unstable": ["kv", "cron", "temporal", "ffi"]
}
```

Or via CLI: `deno run --unstable-kv --unstable-cron main.ts`.

**Q: What is `nodeModulesDir` and when should I use it?**
A: Setting `"nodeModulesDir": "auto"` in `deno.json` makes Deno create a local `node_modules` directory. Use it when tools (bundlers, editors, etc.) expect `node_modules` to exist.

### Tooling

**Q: Can I use Deno's formatter for non-TypeScript files?**
A: Yes. `deno fmt` formats TypeScript, JavaScript, JSON, JSONC, and Markdown files.

**Q: How do I integrate Deno with CI/CD?**
A: A typical CI pipeline:

```yaml
# .github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: denoland/setup-deno@v2
        with:
          deno-version: v2.7.12
      - run: deno lint
      - run: deno fmt --check
      - run: deno check main.ts
      - run: deno test --allow-read --parallel
```

**Q: Does Deno have a package.json equivalent?**
A: `deno.json` serves a similar role. Deno also reads `package.json` for backward compatibility when present.

**Q: Can I debug Deno programs?**
A: Yes. Use `--inspect` or `--inspect-brk`:

```bash
deno run --inspect-brk main.ts
```

Then open `chrome://inspect` in Chrome or attach from VS Code.

**Q: How do I profile Deno performance?**
A: Use V8's built-in profiler:

```bash
deno run --v8-flags=--prof main.ts
# Process the generated .log file
deno run --v8-flags=--prof-process isolate-*.log
```

### Deployment

**Q: How do I deploy Deno to production?**
A: Several options: (1) `deno compile` to a standalone binary, (2) Docker using `denoland/deno` as the base image, (3) Deno Deploy for serverless, (4) any Linux server with Deno installed.

**Q: What is Deno Deploy?**
A: Deno Deploy is a serverless edge platform by the Deno team. Deploy directly with `deno deploy` or connect a GitHub repository for automatic deployments.

**Q: Can I use Deno in AWS Lambda?**
A: Yes, via a custom runtime layer or by compiling to a standalone binary and using the provided.al2 runtime.

**Q: What is the minimum Docker image size for Deno?**
A: The `denoland/deno:alpine` image is approximately 140 MB. For the smallest image, use `deno compile` and copy only the binary into a `FROM scratch` or `FROM alpine` image.

### Compatibility

**Q: Does Deno support Web Workers?**
A: Yes. Use the standard `Worker` API with `{ type: "module" }`.

**Q: Does Deno support WebAssembly?**
A: Yes. Both `WebAssembly.instantiate()` and `.wasm` file imports work.

**Q: Can Deno call C/C++/Rust libraries?**
A: Yes, via the Foreign Function Interface (`Deno.dlopen()`). Requires `--allow-ffi` and `--unstable-ffi`.

**Q: Does Deno support HTTP/2?**
A: Yes. Both the `node:http2` polyfill and Deno's native server support HTTP/2.

**Q: What about WASI (WebAssembly System Interface)?**
A: Deno includes a `node:wasi` polyfill. Native WASI support is available via the `--unstable-wasi` flag.

**Q: How does Deno handle `__dirname` and `__filename`?**
A: These Node.js globals do not exist in Deno. Use:

```typescript
const __filename = new URL(import.meta.url).pathname;
const __dirname = new URL(".", import.meta.url).pathname;

// Or on all platforms:
import { fromFileUrl, dirname } from "@std/path";
const __filename = fromFileUrl(import.meta.url);
const __dirname = dirname(__filename);
```

---

## Environment Variable Reference

| Variable | Purpose | Default |
|----------|---------|---------|
| `DENO_DIR` | Cache directory for remote modules | `~/.cache/deno` (Linux), `~/Library/Caches/deno` (macOS), `%LOCALAPPDATA%\deno` (Windows) |
| `DENO_V8_FLAGS` | V8 engine flags (e.g., `--max-old-space-size=4096`) | (none) |
| `DENO_JOBS` | Number of parallel jobs for `deno test --parallel` | CPU count |
| `DENO_CERT` | Path to a PEM certificate for TLS | (none) |
| `DENO_DEPLOY_TOKEN` | Authentication token for Deno Deploy | (none) |
| `DENO_SERVE_ADDRESS` | Default address for `deno serve` | `0.0.0.0:8000` |
| `DENO_AUTO_SERVE` | Enable auto-serve mode | (none) |
| `DENO_CANARY` | Use canary channel for `deno upgrade` | (none) |
| `DENO_WEBGPU_BACKEND` | WebGPU backend selection | (auto) |
| `DENO_KV_ACCESS_TOKEN` | KV access token for remote KV stores | (none) |
| `DENO_AUDIT_PERMISSIONS` | Enable permission audit logging | (none) |
| `DENO_CONDITIONS` | Custom module resolution conditions | (none) |
| `DENO_UNSTABLE_*` | Enable specific unstable features | (none) |
| `NO_COLOR` | Disable colored terminal output (any value) | (none) |
| `HTTP_PROXY` | HTTP proxy URL | (none) |
| `HTTPS_PROXY` | HTTPS proxy URL | (none) |
| `NO_PROXY` | Comma-separated hosts to bypass proxy | (none) |
| `NODE_OPTIONS` | Node.js-compatible runtime options | (none) |
| `NODE_PATH` | Additional Node module resolution paths | (none) |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OpenTelemetry OTLP endpoint URL | (none) |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP protocol (`grpc`, `http/protobuf`) | (none) |
| `OTEL_SERVICE_NAME` | Service name for OpenTelemetry traces | (none) |

## CLI Command Reference

| Command | Purpose | Key Flags |
|---------|---------|-----------|
| `deno run <script>` | Run a script | `--watch`, `--check`, `--inspect`, `-A` |
| `deno test` | Run tests | `--parallel`, `--filter`, `--coverage`, `--doc` |
| `deno bench` | Run benchmarks | `--filter`, `--json` |
| `deno fmt` | Format code | `--check`, `--ext`, `--single-quote` |
| `deno lint` | Lint code | `--json`, `--rules` |
| `deno check` | Type-check | `--remote`, `--all` |
| `deno doc` | Generate documentation | `--html`, `--json`, `--filter` |
| `deno coverage <dir>` | View coverage report | `--lcov`, `--html`, `--output` |
| `deno compile` | Compile to binary | `--target`, `--output`, `--include` |
| `deno bundle` | Bundle modules (legacy) | `--watch` |
| `deno task <name>` | Run a task from deno.json | (none) |
| `deno install` | Install dependencies | `--global`, `--name` |
| `deno add <pkg>` | Add a dependency | (none) |
| `deno remove <pkg>` | Remove a dependency | (none) |
| `deno audit` | Audit dependencies | (none) |
| `deno outdated` | Check for outdated deps | `--update` |
| `deno repl` | Interactive REPL | `--eval`, `--eval-file` |
| `deno jupyter` | Install Jupyter kernel | `--install` |
| `deno publish` | Publish to JSR | `--dry-run`, `--token` |
| `deno deploy` | Deploy to Deno Deploy | `--project`, `--entrypoint` |
| `deno init [dir]` | Initialize a new project | (none) |
| `deno upgrade` | Upgrade Deno | `--version`, `--canary` |
| `deno uninstall` | Uninstall a global package | `--global` |
| `deno serve <script>` | Serve HTTP | `--port`, `--parallel` |
| `deno eval <code>` | Evaluate code | `--ext`, `--print` |
| `deno cache <files>` | Cache dependencies | `--reload`, `--lock` |
| `deno info [file]` | Show dependency tree / cache info | `--json` |
| `deno types` | Print TypeScript declarations | (none) |
| `deno completions <shell>` | Generate shell completions | (none) |
| `deno lsp` | Start Language Server Protocol | (none) |

---

_Generated May 2026 from denoland/deno at 7529c84. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
