diff --git a/api/web/index.md b/api/web/index.md index 356b46655..a819cec84 100644 --- a/api/web/index.md +++ b/api/web/index.md @@ -72,6 +72,55 @@ Deno supports a comprehensive set of web standard APIs: - **[Timers](/api/web/~/setTimeout)** - setTimeout, setInterval, and setImmediate +### Structured Clone & Transferable Objects + +Deno supports [`structuredClone()`](/api/web/~/structuredClone) and +[`postMessage()`](/api/web/~/Worker) for cloning and transferring objects across +contexts (e.g. between the main thread and Web Workers). + +#### Serializable types + +These types can be cloned with `structuredClone()` and sent via `postMessage()`: + +| Type | Notes | +| ----------------------------------------- | -------------------------------------------------------------------------------------------- | +| Primitives | `string`, `number`, `boolean`, `null`, `undefined`, `bigint` | +| `Array`, `Object`, `Map`, `Set` | Including nested structures and circular references | +| `Date`, `RegExp` | | +| `ArrayBuffer`, `TypedArray`, `DataView` | Copied by default, or transferred (see below) | +| `Error` types | `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, `URIError` | +| [`Blob`](/api/web/~/Blob) | Requires Deno 2.8+ | +| [`File`](/api/web/~/File) | Requires Deno 2.8+ | +| [`DOMException`](/api/web/~/DOMException) | | +| [`CryptoKey`](/api/web/~/CryptoKey) | | + +#### Transferable types + +These types can be _transferred_ (not copied) via the `transfer` option in +`structuredClone()` or the `transfer` list in `postMessage()`. After transfer, +the original object becomes unusable: + +| Type | Notes | +| ----------------------------------------------- | ---------------------------------------- | +| [`ArrayBuffer`](/api/web/~/ArrayBuffer) | Moves the backing memory to the receiver | +| [`MessagePort`](/api/web/~/MessagePort) | Transfers the port to another context | +| [`ReadableStream`](/api/web/~/ReadableStream) | Transfers the stream to another context | +| [`WritableStream`](/api/web/~/WritableStream) | Transfers the stream to another context | +| [`TransformStream`](/api/web/~/TransformStream) | Transfers the stream to another context | + +```ts +// Clone a Blob +const blob = new Blob(["hello"], { type: "text/plain" }); +const cloned = structuredClone(blob); +console.log(await cloned.text()); // "hello" + +// Transfer an ArrayBuffer through a MessageChannel +const buffer = new ArrayBuffer(1024); +const ch = new MessageChannel(); +ch.port1.postMessage(buffer, [buffer]); +// buffer.byteLength is now 0 (transferred) +``` + ## Key Benefits - **Standards Compliance**: APIs follow WHATWG and W3C specifications diff --git a/examples/scripts/importing_text.ts b/examples/scripts/importing_text.ts index 6268528ed..f30c4ff5e 100644 --- a/examples/scripts/importing_text.ts +++ b/examples/scripts/importing_text.ts @@ -2,14 +2,15 @@ * @title Importing text files * @difficulty beginner * @tags cli - * @run --unstable-raw-imports https://docs.deno.com/examples/scripts/importing_text.ts + * @run * @resource {https://github.com/whatwg/html/issues/9444} HTML specification proposal - * @group Unstable APIs + * @group Basics * * Text files can be imported in JS and TS files using the `import` keyword. * This makes including static data in a library much easier. * - * Using this feature requires `--unstable-raw-imports` CLI flag. + * Stable as of Deno 2.8 — no flag required. (Binary `bytes` imports are still + * experimental and require `--unstable-raw-imports`.) */ // File: ./main.ts diff --git a/examples/tutorials/os_signals.md b/examples/tutorials/os_signals.md index 0a5d52743..f05c2ae2e 100644 --- a/examples/tutorials/os_signals.md +++ b/examples/tutorials/os_signals.md @@ -1,5 +1,5 @@ --- -last_modified: 2025-03-10 +last_modified: 2026-05-20 title: "Handle OS signals" description: "Tutorial on handling operating system signals in Deno. Learn how to capture SIGINT and SIGBREAK events, manage signal listeners, and implement graceful shutdown handlers in your applications." url: /examples/os_signals_tutorial/ @@ -8,7 +8,9 @@ oldUrl: - /runtime/tutorials/os_signals/ --- -> ⚠️ Windows only supports listening for SIGINT and SIGBREAK as of Deno v1.23. +> ⚠️ Windows supports listening for `SIGINT`, `SIGBREAK`, `SIGTERM`, `SIGQUIT`, +> `SIGHUP`, and `SIGWINCH` (all except `SIGINT`/`SIGBREAK` go through libuv's +> Windows signal emulation). ## Concepts @@ -75,3 +77,18 @@ Run with: ```shell deno run signal_listeners.ts ``` + +## Windows support + +The supported signal set differs between platforms. The Windows-specific +behavior is: + +| Use case | Supported signals on Windows | +| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `Deno.addSignalListener(sig, …)` | `SIGINT`, `SIGBREAK`, `SIGTERM`, `SIGQUIT`, `SIGHUP`, `SIGWINCH` | +| `Deno.kill(pid, sig)` | `SIGINT`, `SIGBREAK`, `SIGTERM`, `SIGQUIT`, `SIGHUP`, `SIGWINCH`, `SIGKILL`, `SIGABRT`, plus signal `0` for a process-health check | + +`SIGKILL` and `SIGABRT` are deliberately **not** registerable via +`addSignalListener` — they're uncatchable / fatal, matching Unix semantics. On +Windows the catchable signals all forward to libuv's emulation layer; signals +sent via `Deno.kill` ultimately invoke `TerminateProcess`. diff --git a/lint/rules/no-node-globals.md b/lint/rules/no-node-globals.md index 30e905f01..6db746d7d 100644 --- a/lint/rules/no-node-globals.md +++ b/lint/rules/no-node-globals.md @@ -1,5 +1,5 @@ --- -tags: [recommended] +tags: [] --- Disallows the use of NodeJS global objects. @@ -8,6 +8,19 @@ NodeJS exposes a set of global objects that differs from deno (and the web), so code should not assume they are available. Instead, import the objects from their defining modules as needed. +This rule is **off by default** as of Deno 2.8. To opt in, add it to your +`deno.json`: + +```json +{ + "lint": { + "rules": { + "include": ["no-node-globals"] + } + } +} +``` + **Invalid:** ```typescript diff --git a/lint/rules/no-process-global.md b/lint/rules/no-process-global.md index c5ee9c509..d3ee1a1f8 100644 --- a/lint/rules/no-process-global.md +++ b/lint/rules/no-process-global.md @@ -1,5 +1,5 @@ --- -tags: [recommended] +tags: [] --- Disallows the use of NodeJS `process` global. @@ -8,6 +8,19 @@ NodeJS and Deno expose `process` global but they are hard to statically analyze by tools, so code should not assume they are available. Instead, `import process from "node:process"`. +This rule is **off by default** as of Deno 2.8. To opt in, add it to your +`deno.json`: + +```json +{ + "lint": { + "rules": { + "include": ["no-process-global"] + } + } +} +``` + **Invalid:** ```typescript diff --git a/runtime/_data.ts b/runtime/_data.ts index 3fbe9a364..a0499211d 100644 --- a/runtime/_data.ts +++ b/runtime/_data.ts @@ -116,6 +116,10 @@ export const sidebar = [ title: "deno bench", href: "/runtime/reference/cli/bench/", }, + { + title: "deno bump-version", + href: "/runtime/reference/cli/bump_version/", + }, { title: "deno bundle", href: "/runtime/reference/cli/bundle/", @@ -124,6 +128,10 @@ export const sidebar = [ title: "deno check", href: "/runtime/reference/cli/check/", }, + { + title: "deno ci", + href: "/runtime/reference/cli/ci/", + }, { title: "deno clean", href: "/runtime/reference/cli/clean/", @@ -184,6 +192,10 @@ export const sidebar = [ title: "deno outdated", href: "/runtime/reference/cli/outdated/", }, + { + title: "deno pack", + href: "/runtime/reference/cli/pack/", + }, { title: "deno publish", href: "/runtime/reference/cli/publish/", @@ -220,6 +232,10 @@ export const sidebar = [ title: "deno test", href: "/runtime/reference/cli/test/", }, + { + title: "deno transpile", + href: "/runtime/reference/cli/transpile/", + }, { title: "deno types", href: "/runtime/reference/cli/types/", @@ -240,6 +256,10 @@ export const sidebar = [ title: "deno unstable flags", href: "/runtime/reference/cli/unstable_flags/", }, + { + title: "deno why", + href: "/runtime/reference/cli/why/", + }, { title: "deno x", href: "/runtime/reference/cli/x/", @@ -330,6 +350,10 @@ export const sidebar = [ title: "Lint plugins", href: "/runtime/reference/lint_plugins/", }, + { + title: "Module customization hooks", + href: "/runtime/reference/module_hooks/", + }, { title: "WebAssembly", href: "/runtime/reference/wasm/", diff --git a/runtime/fundamentals/configuration.md b/runtime/fundamentals/configuration.md index 47c812139..415da98a0 100644 --- a/runtime/fundamentals/configuration.md +++ b/runtime/fundamentals/configuration.md @@ -744,6 +744,27 @@ this requires an explicit opt-in with `-P` and is not loaded by default. If you're ok with this risk, then this feature will be useful for you. +## Compile config + +The `"compile"` block configures +[`deno compile`](/runtime/reference/cli/compile/) without requiring you to +repeat flags on every invocation. You can declare which extra files or +directories to bundle into the executable, and which paths to exclude: + +```jsonc title="deno.json" +{ + "compile": { + "include": ["names.csv", "data", "worker.ts"], + "exclude": ["data/secrets", "**/*.test.ts"] + } +} +``` + +`--include` and `--exclude` flags on the command line are merged with these +lists rather than replacing them. The `"compile"` block can also carry +`permissions` (see +[Test, bench, and compile permissions](#test-bench-and-compile-permissions)). + ## An example `deno.json` file ```json diff --git a/runtime/fundamentals/debugging.md b/runtime/fundamentals/debugging.md index 2b510fc5e..59121a9e3 100644 --- a/runtime/fundamentals/debugging.md +++ b/runtime/fundamentals/debugging.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-19 +last_modified: 2026-05-20 title: "Debugging" description: "Complete guide to debugging Deno applications. Learn to use Chrome DevTools, VS Code debugger, and other debugging techniques for TypeScript/JavaScript code in Deno." oldUrl: @@ -126,6 +126,144 @@ curl http://0.0.0.0:4507/ At this point we can introspect the contents of the request and go step-by-step to debug the code. +## Inspecting network traffic + +Starting with Deno 2.8, Chrome DevTools can inspect network traffic made by your +program in the same way it inspects traffic in a browser tab. Run your program +with `--inspect-wait` (or `--inspect` / `--inspect-brk`), open +`chrome://inspect` in a Chromium derived browser, click **Inspect** on the Deno +target, and switch to the **Network** tab. + +The following built-in APIs are wired into the Network tab: + +- `fetch()` — requests appear with `Type: fetch` +- `node:http` and `node:https` client requests (`http.request`, `http.get`, + `https.request`, `https.get`) — the **Type** column reflects the response + content-type (e.g. `json`, `document`), so any npm library that issues HTTP + requests through `node:http` shows up alongside `fetch()` traffic +- `WebSocket` — client connections appear alongside HTTP requests, with + handshake status and headers from the upgrade response, message frames, and a + close event when the socket is closed +- [`Deno.upgradeWebSocket()`](/api/deno/~/Deno.upgradeWebSocket) — server-side + WebSocket upgrades are instrumented too, so you can inspect both sides of a + connection from a Deno-to-Deno handshake + +For each request you can see the URL, method, status code, request and response +headers, request and response bodies, and timing information. + +Let's try it with a small program that uses `fetch()`: + +```ts title="net.ts" +const res = await fetch("https://api.github.com/repos/denoland/deno"); +console.log(res.status, (await res.json()).stargazers_count); +``` + +Run it with `--inspect-wait` so the program pauses until DevTools connects: + +```sh +$ deno run --inspect-wait --allow-net net.ts +Debugger listening on ws://127.0.0.1:9229/... +Visit chrome://inspect to connect to the debugger. +Deno is waiting for debugger to connect. +``` + +Open `chrome://inspect`, click **Inspect** on the Deno target, and switch to the +**Network** tab. The `fetch()` request shows up as a regular network entry, with +the request and response panes populated: + +![fetch() request in the Network tab](./images/debugger-network-fetch.png) + +Click a request to see its headers, payload, response body, and timing +breakdown: + +![Inspecting response headers and body](./images/debugger-network-response.png) + +The same applies to `node:http` and `node:https`, so npm libraries that issue +HTTP requests through Node's built-in client (rather than `fetch()`) also show +up in the Network tab. For example: + +```ts title="node-http.ts" +import https from "node:https"; + +const options = { + hostname: "api.github.com", + path: "/repos/denoland/deno", + headers: { "User-Agent": "deno-docs-example" }, +}; + +https.get(options, (res) => { + let body = ""; + res.on("data", (chunk) => body += chunk); + res.on( + "end", + () => console.log(res.statusCode, JSON.parse(body).stargazers_count), + ); +}); +``` + +```sh +$ deno run --inspect-wait --allow-net node-http.ts +``` + +The request appears in the Network tab with the same headers, body, and timing +information as a `fetch()` request — the **Type** column reflects the response +content-type (`json` for this example): + +![node:https request in the Network tab](./images/debugger-network-node-http.png) + +`WebSocket` connections appear in the same Network tab, with messages and the +close event surfaced as the connection progresses: + +![WebSocket connection in the Network tab](./images/debugger-network-websocket.png) + +Server-side WebSockets created with +[`Deno.upgradeWebSocket()`](/api/deno/~/Deno.upgradeWebSocket) are also +instrumented, so you can inspect both sides of a connection — the outgoing +client `WebSocket` and the server upgrade that accepts it. For example, a small +echo server: + +```ts title="ws-server.ts" +Deno.serve({ port: 8000 }, (req) => { + if (req.headers.get("upgrade") !== "websocket") { + return new Response("send a WebSocket request", { status: 426 }); + } + const { socket, response } = Deno.upgradeWebSocket(req); + socket.onmessage = (e) => socket.send(`echo: ${e.data}`); + return response; +}); +``` + +```sh +$ deno run --inspect-wait --allow-net ws-server.ts +``` + +After connecting DevTools and resuming execution, connect to the server from +another terminal (for example with `deno eval`): + +```sh +deno eval 'const ws = new WebSocket("ws://localhost:8000"); + ws.onopen = () => ws.send("hello"); + ws.onmessage = (e) => { console.log(e.data); ws.close(); };' +``` + +The upgrade and the message frames show up in the Network tab of the server's +DevTools session: + +![Deno.upgradeWebSocket() in the Network tab](./images/debugger-network-upgrade-websocket.png) + +The same events are also exposed through `node:inspector` for programmatic +clients, so tooling that already speaks the Chrome DevTools Protocol against +Node can attach to Deno and observe the same network traffic without any +changes. + +:::note + +When no debugger is attached, the network instrumentation has effectively no +overhead — the events are only emitted while a session has opted in via +`Network.enable`. + +::: + ## VSCode Deno can be debugged using VSCode. This is best done with help from the official @@ -212,6 +350,27 @@ directly. ::: +### Customizing profile output + +By default, profiles are written to the current directory with an auto-generated +filename. You can control where and how profiles are saved: + +```sh +# Save profiles to a specific directory +deno run --cpu-prof --cpu-prof-dir=./profiles your_script.ts + +# Use a custom filename +deno run --cpu-prof --cpu-prof-name=my-profile.cpuprofile your_script.ts + +# Increase sampling frequency for more detail (default: 1000μs) +deno run --cpu-prof --cpu-prof-interval=100 your_script.ts +``` + +A lower `--cpu-prof-interval` captures more samples per second, giving finer +granularity at the cost of larger profile files. The default of `1000` +microseconds (1ms) is a good balance for most use cases. For short-lived +functions you want to capture in detail, try `100` (0.1ms). + ### Analyzing profiles in Chrome DevTools To analyze the `.cpuprofile` file: @@ -304,6 +463,29 @@ The flamegraph also works with `deno eval`: deno eval --cpu-prof --cpu-prof-flamegraph "for (let i = 0; i < 1e8; i++) {}" ``` +### Profiling tips + +- **Profile representative workloads**: For HTTP servers, send realistic traffic + to the server before stopping it — the profile only captures what happens + while the program is running. +- **Use self time vs. total time**: In profile reports, _self time_ is time + spent in a function's own code, while _total time_ includes time in functions + it calls. High self time points to the actual bottleneck; high total time with + low self time means the function delegates to something expensive. +- **Compare before and after**: Save profiles with descriptive `--cpu-prof-name` + values (e.g., `before-optimization.cpuprofile`) so you can compare profiles + side-by-side in DevTools after making changes. +- **Combine output formats**: You can use `--cpu-prof-md` and + `--cpu-prof-flamegraph` together to get all three outputs (`.cpuprofile`, + `.md`, and `.svg`) in a single run: + ```sh + deno run --cpu-prof --cpu-prof-md --cpu-prof-flamegraph your_script.ts + ``` +- **Filter out noise**: Short-lived programs may show startup overhead (module + loading, JIT compilation) dominating the profile. For more accurate results, + ensure the code you want to profile runs long enough to collect meaningful + samples. + ## OpenTelemetry integration For production applications or complex systems, OpenTelemetry provides a more diff --git a/runtime/fundamentals/images/debugger-network-fetch.png b/runtime/fundamentals/images/debugger-network-fetch.png new file mode 100644 index 000000000..e4c32b790 Binary files /dev/null and b/runtime/fundamentals/images/debugger-network-fetch.png differ diff --git a/runtime/fundamentals/images/debugger-network-node-http.png b/runtime/fundamentals/images/debugger-network-node-http.png new file mode 100644 index 000000000..913e4aba5 Binary files /dev/null and b/runtime/fundamentals/images/debugger-network-node-http.png differ diff --git a/runtime/fundamentals/images/debugger-network-response.png b/runtime/fundamentals/images/debugger-network-response.png new file mode 100644 index 000000000..144c01433 Binary files /dev/null and b/runtime/fundamentals/images/debugger-network-response.png differ diff --git a/runtime/fundamentals/images/debugger-network-upgrade-websocket.png b/runtime/fundamentals/images/debugger-network-upgrade-websocket.png new file mode 100644 index 000000000..ae82ad230 Binary files /dev/null and b/runtime/fundamentals/images/debugger-network-upgrade-websocket.png differ diff --git a/runtime/fundamentals/images/debugger-network-websocket.png b/runtime/fundamentals/images/debugger-network-websocket.png new file mode 100644 index 000000000..b2deeb695 Binary files /dev/null and b/runtime/fundamentals/images/debugger-network-websocket.png differ diff --git a/runtime/fundamentals/modules.md b/runtime/fundamentals/modules.md index 7644732ab..7263a691f 100644 --- a/runtime/fundamentals/modules.md +++ b/runtime/fundamentals/modules.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-05 +last_modified: 2026-05-20 title: "Modules and dependencies" description: "A guide to managing modules and dependencies in Deno. Learn about ECMAScript modules, third-party packages, import maps, dependency management, versioning, and how to publish your own modules." oldUrl: @@ -78,14 +78,6 @@ console.log(data.property); // Access JSON data as an object Starting with Deno 2.4 it's possible to import `text` and `bytes` modules too. -:::info - -Support for importing `text` and `bytes` modules is experimental and requires -`--unstable-raw-imports` CLI flag or `unstable.raw-import` option in -[`deno.json`](/runtime/fundamentals/configuration/). - -::: - ```ts import text from "./log.txt" with { type: "text" }; @@ -95,6 +87,12 @@ console.log(text); // Hello from a text file ``` +:::info `text` imports + +Stable in Deno 2.8 and no longer require a flag. + +::: + ```ts import bytes from "./image.png" with { type: "bytes" }; @@ -108,6 +106,38 @@ Uint8Array(12) [ // ] ``` +:::info `bytes` imports + +Still experimental. Enable with the `--unstable-raw-imports` CLI flag or the +`unstable.raw-import` option in +[`deno.json`](/runtime/fundamentals/configuration/). + +::: + +## Deferred module evaluation + +Starting in Deno 2.8, the +[TC39 Deferred Module Evaluation proposal](https://github.com/tc39/proposal-defer-import-eval) +is supported. The `import defer` syntax loads a module (including its +dependencies) but does **not** execute its top-level code until you first read a +property from the namespace: + +```ts title="main.ts" +import defer * as expensive from "./expensive.ts"; + +console.log("startup is fast — expensive.ts has not run yet"); + +// Touching any property triggers synchronous evaluation +console.log(expensive.value); +``` + +Use it to defer the cost of modules that are only needed conditionally; for +example, error-path code in a CLI tool or feature flags whose implementation is +heavy to initialize. + +The proposal is still at TC39 Stage 3, so the syntax is considered experimental +and may change. Standard `import` remains the right default. + ## WebAssembly modules Deno supports importing Wasm modules directly: @@ -271,6 +301,15 @@ $ deno add jsr:@luca/cases@1.0.0 Add @luca/cases - jsr:@luca/cases@1.0.0 ``` +:::info Deno 2.8 + +Unprefixed package names passed to `deno add` / `deno install` are treated as +npm packages by default. `deno add express` is now equivalent to +`deno add npm:express`. JSR packages still need the `jsr:` prefix to stay +unambiguous. + +::: + Read more in [`deno add` reference](/runtime/reference/cli/add/). You can also remove dependencies using `deno remove`: @@ -292,7 +331,9 @@ Read more in [`deno remove` reference](/runtime/reference/cli/remove/). It is possible to specify a version range for the package you are importing. This is done using the `@` symbol followed by a version range specifier, and -follows the [semver](https://semver.org/) versioning scheme. +follows the [semver](https://semver.org/) versioning scheme. If you need to +share a single version range across multiple workspace members, see +[`catalog:` for centralized dependency versions](/runtime/fundamentals/workspaces/#centralized-dependency-versions-with-catalog). For example: @@ -508,8 +549,10 @@ Modules can be published to: - [JSR](https://jsr.io) - recommended, supports TypeScript natively and auto-generates documentation for you -- [npm](https://www.npmjs.com/) - use [dnt](https://github.com/denoland/dnt) to - create the npm package +- [npm](https://www.npmjs.com/) - use + [`deno pack`](/runtime/reference/cli/pack/) (Deno 2.8+) to build an + npm-compatible tarball from a Deno project, or + [dnt](https://github.com/denoland/dnt) for a more configurable build pipeline - [deno.land/x](https://deno.com/add_module) - for HTTPS imports, use JSR instead if possible @@ -624,12 +667,17 @@ are semantically "development time" dependencies, like (`@types/*`), are often defined in `dependencies` in `package.json` files, which means they are installed for production even though they are not needed. -Because of this, Deno uses a different approach for installing production only -dependencies: when running `deno install`, you can pass a `--entrypoint` flag -that causes Deno to install only the dependencies that are actually -(transitively) imported by the specified entrypoint file. Because this is -automatic, and works based on the actual code that is being executed, there is -no need to specify development dependencies in a separate field. +Deno offers two approaches for installing production-only dependencies: + +- **`deno install --prod`** — skips `devDependencies` from `package.json`. You + can also pass `--skip-types` to additionally exclude `@types/*` packages. +- **`deno install --entrypoint`** — installs only the dependencies that are + actually (transitively) imported by the specified entrypoint file. When + combined with `--prod`, type-only dependencies are also excluded from the + module graph. + +See the [`deno install` reference](/runtime/reference/cli/install/) for more +details. ## Using only cached modules @@ -739,9 +787,58 @@ local workspaces). Good supply chain management helps you achieve four goals: codebases to centralize version changes. 6. Periodically unfreeze and update consciously (for example on a weekly or sprint cadence) instead of ad‑hoc updates during feature work. +7. Set a [minimum dependency age](#minimum-dependency-age) so freshly published + versions can't slip into an install before the ecosystem has had time to spot + a compromised release. + +### Minimum dependency age + +Deno can refuse to install any package version that is younger than a configured +age. This is a cheap, broad defence against npm supply-chain attacks: malicious +versions are usually detected and yanked within days, so delaying installs by a +similar window catches the bulk of them. + +You can configure the same control in three places; pick whichever fits the +project: + +- **`deno.json`**, apply project-wide: + + ```jsonc title="deno.json" + { + "minimumDependencyAge": "72h" + } + ``` + +- **CLI flag**, apply ad-hoc, e.g. for a one-off install or in a CI step: + + ```sh + deno install --minimum-dependency-age=72h + ``` + +- **`.npmrc`** (Deno 2.8+), matches the npm convention, useful when sharing the + same `.npmrc` across npm and Deno tooling: + + ```ini title=".npmrc" + min-release-age=72h + ``` + +Values accept human-friendly durations (`72h`, `P2D`), absolute cutoff dates +(`2025-09-16`), or `0` to disable. See +[`.npmrc` configuration](/runtime/fundamentals/node/#npmrc-configuration) for +the other npm-registry options Deno reads. ### Typical CI pattern +In Deno 2.8+, the single command [`deno ci`](/runtime/reference/cli/ci/) +encapsulates the recommended CI install flow (frozen lockfile + lifecycle +scripts): + +```sh +deno ci +``` + +For older Deno versions, or to compose the steps manually: + ```sh # Install (resolve) dependencies exactly as locked; fail if drift or new deps deno install --frozen --entrypoint main.ts @@ -751,8 +848,8 @@ deno run --cached-only main.ts ``` If you rely on `npm` packages (`package.json` present), include `deno install` -in CI before running tests so the `node_modules` directory is materialized -deterministically. +(or `deno ci`) in CI before running tests so the `node_modules` directory is +materialized deterministically. ### Updating dependencies intentionally diff --git a/runtime/fundamentals/node.md b/runtime/fundamentals/node.md index 139180888..2abeb715b 100644 --- a/runtime/fundamentals/node.md +++ b/runtime/fundamentals/node.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-02-10 +last_modified: 2026-05-20 title: "Node and npm Compatibility" description: "Guide to using Node.js modules and npm packages in Deno. Learn about compatibility features, importing npm packages, and differences between Node.js and Deno environments." oldUrl: @@ -33,6 +33,10 @@ That's all you really need to know to get started! However, there are some key differences between the two runtimes that you can take advantage of to make your code simpler and smaller when migrating your Node.js projects to Deno. +As of Deno 2.8, **over 75% of Node's own test suite passes** in Deno, covering +nearly every `node:` module. You can track the current state at +[node-test-viewer.deno.dev](https://node-test-viewer.deno.dev/). + We provide a [list of supported Node.js APIs](/runtime/reference/node_apis/) that you can use in Deno. @@ -104,6 +108,10 @@ error: Relative import path "os" not prefixed with / or ./ or ../ The same hints and additional quick-fixes are provided by the Deno LSP in your editor. +The `node:module` built-in includes the +[`registerHooks()`](/runtime/reference/module_hooks/) API, which you can use to +customize module resolution and loading from inside your program. + Explore built-in Node APIs ## Using npm packages @@ -172,9 +180,10 @@ Here are a few globals that you might encounter in the wild and how to use them in Deno: - `process` - Deno provides the `process` global, which is by far the most - popular global used in popular npm packages. It is available to all code. - However, Deno will guide you towards importing it explicitly from - `node:process` module by providing lint warnings and quick-fixes: + popular global used in popular npm packages. It is available to all code. Deno + can also guide you towards importing it explicitly from `node:process`. Opt in + by enabling the [`no-process-global`](/lint/rules/no-process-global/) lint + rule (off by default since Deno 2.8): ```js title="process.js" console.log(process.versions.deno); @@ -231,6 +240,21 @@ subclasses instead. - `__dirname` - use `import.meta.dirname` instead. +- `setTimeout` / `setInterval` - starting in Deno 2.8, the global timer + functions return a Node.js + [`Timeout`](https://nodejs.org/api/timers.html#class-timeout) object instead + of a number, matching Node.js semantics. The returned object exposes methods + like `.ref()`, `.unref()`, `.refresh()`, and `.hasRef()`. It still coerces to + a number (via `Symbol.toPrimitive`), so existing code that stores the timer ID + as a number or passes it to `clearTimeout`/`clearInterval` continues to work + unchanged. + + ```ts + const t = setTimeout(() => {}, 1000); + t.unref(); // don't keep the event loop alive for this timer + clearTimeout(t); + ``` + ## CommonJS support Deno supports CommonJS modules by default. @@ -471,17 +495,35 @@ resolution, you can: ## Including Node types -Node ships with many built-in types like `Buffer` that might be referenced in an -npm package's types. To load these you must add a types reference directive to -the `@types/node` package: +Starting in Deno 2.8, `deno check` and the LSP include `lib.node` in every +type-check by default, so Node ambient types like `Buffer`, `NodeJS.Timeout`, +and `process` resolve without any configuration: ```ts -/// +// 2.8+: type-checks with no extra setup +const buf: Buffer = Buffer.from("hello"); +const t: NodeJS.Timeout = setTimeout(() => {}, 0); ``` -Note that it is fine to not specify a version for this in most cases because -Deno will try to keep it in sync with its internal Node code, but you can always -override the version used if necessary. +The bundled `lib.node` tracks the major version of `@types/node` that matches +the Node release Deno reports in `process.versions.node`. If you need to pin a +specific `@types/node` version (for example to match the Node version your +project standardises on), add it as an explicit dependency: + +```jsonc title="deno.json" +{ + "imports": { + "@types/node": "npm:@types/node@^22" + } +} +``` + +On versions before 2.8 — or if you've opted out of `lib.node` — you can still +load the types with a reference directive: + +```ts +/// +``` ## Run npm binaries @@ -627,6 +669,57 @@ Running the above command, with a `--node-modules-dir` flag, will create a `node_modules` folder in the current directory with a similar folder structure to npm. +### node_modules layout: isolated vs hoisted + +When a local `node_modules` directory exists, Deno can lay it out in two ways. +The default (**isolated**) installs each package into a content-addressed +`.deno/` directory and exposes it through a symlink, so every package only sees +its declared dependencies. This is similar to pnpm's layout. + +```text +node_modules/ +├── .deno/chalk@5.6.2/node_modules/chalk/ ← real files +└── chalk -> .deno/chalk@5.6.2/node_modules/chalk +``` + +Some npm tooling, and any package that walks `node_modules` looking for +flat-resolved siblings, assumes the **hoisted** layout that npm and Yarn classic +use. Deno 2.8 adds a hoisted mode +([denoland/deno#32788](https://github.com/denoland/deno/pull/32788)) you can opt +into with `nodeModulesLinker` in `deno.json`. The hoisted linker requires a +manually-managed `node_modules` directory, so set `nodeModulesDir` to `manual`: + +```json title="deno.json" +{ + "nodeModulesDir": "manual", + "nodeModulesLinker": "hoisted" +} +``` + +Or as a one-off CLI flag (also requiring `--node-modules-dir=manual`): + +```sh +deno install --node-modules-dir=manual --node-modules-linker=hoisted +``` + +In hoisted mode the most-depended-upon version of each package is placed at the +top of `node_modules/`, and conflicting versions are nested under the dependent +that needs them, just like npm: + +```text +node_modules/ +├── chalk/ ← real files +├── express/ +├── ms/ ← hoisted: most commonly needed version +└── debug/ + └── node_modules/ + └── ms/ ← nested: a different version +``` + +Stick with the default isolated mode unless a tool you depend on requires the +hoisted layout. Isolated mode catches phantom dependencies that hoisted layouts +hide. + ## Node-API addons Summary: Node-API addons work in Deno when a local `node_modules/` is present @@ -773,6 +866,62 @@ and run it using the `deno run` command: deno run main.ts ``` +### `.npmrc` configuration + +Beyond the basic registry / token setup above, Deno reads several other `.npmrc` +fields. The ones most likely to matter: + +- **Mutual-TLS authentication** (Deno 2.8+): `certfile` and `keyfile` point at + PEM files used to authenticate the client when the registry requires mTLS. + + ```ini title=".npmrc" + //registry.mycompany.com/:certfile=/etc/deno/client.crt + //registry.mycompany.com/:keyfile=/etc/deno/client.key + ``` + +- **`email` on `_auth` entries** (Deno 2.8+): some legacy on-prem registries + require an `email` alongside the auth token. + + ```ini title=".npmrc" + //registry.mycompany.com/:_auth=secretToken + //registry.mycompany.com/:email=ci@mycompany.com + ``` + +- **`min-release-age`** (Deno 2.8+): refuses to install package versions younger + than the configured age. Useful as a default supply-chain guard for all + installs. The same control is also available as the CLI flag + `--minimum-dependency-age` and the `minimumDependencyAge` field in + `deno.json`. See + [Minimum dependency age](/runtime/fundamentals/modules/#minimum-dependency-age) + for the full picture. + + ```ini title=".npmrc" + min-release-age=72h + ``` + +- **`NPM_CONFIG_REGISTRY` env var**: overrides the registry set in `.npmrc`, + matching npm's precedence (handy in CI when you want to redirect installs + without editing the checked-in `.npmrc`). + +### `file:` and `link:` dependencies in published packages + +Some published npm packages accidentally ship a `file:` or `link:` specifier in +their `package.json` that points at a path on the publisher's machine: + +```jsonc title="some-package/package.json" +{ + "dependencies": { + "lodash": "^4.17.0", + "local-helpers": "file:../local-helpers" + } +} +``` + +Starting in Deno 2.8, those `file:` and `link:` entries are silently skipped +while resolving npm metadata, so packages that carry a stray local-path +dependency install cleanly instead of failing with an "Invalid version +requirement" error. + ## Node to Deno Cheatsheet | Node.js | Deno | diff --git a/runtime/fundamentals/open_telemetry.md b/runtime/fundamentals/open_telemetry.md index dce7d351f..505e43575 100644 --- a/runtime/fundamentals/open_telemetry.md +++ b/runtime/fundamentals/open_telemetry.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-25 +last_modified: 2026-05-20 title: OpenTelemetry description: "Learn how to implement observability in Deno applications using OpenTelemetry. Covers tracing, metrics collection, and integration with monitoring systems." --- @@ -288,6 +288,30 @@ environment variable: - `ignore`: Logs are emitted only to stdout/stderr, and will not be exported with OpenTelemetry. +### Permission audit + +Deno can route the permission audit log into the OpenTelemetry exporter +alongside the rest of your traces, metrics, and logs. Set +`DENO_AUDIT_PERMISSIONS=otel` (instead of a file path) and each permission +access — allowed or denied — is emitted as an OpenTelemetry log record with +these attributes: + +- `deno.permission.type` — the permission name (`read`, `net`, `env`, …). +- `deno.permission.value` — the specific value being checked (a path, host, + variable name, etc.). +- `deno.permission.stack` — the JavaScript stack frames at the access site, only + present when `DENO_TRACE_PERMISSIONS` is also set. + +```sh +OTEL_DENO=true DENO_AUDIT_PERMISSIONS=otel deno run -A main.ts +``` + +This is useful when you already collect OpenTelemetry data: the audit lands in +the same backend as your request traces, so you can correlate which request +triggered which permission access. See +[permission audit](/runtime/fundamentals/security/#permission-flags) for the +full attribute set and the JSONL file-path mode. + ## User metrics In addition to the automatically collected telemetry data, you can also create @@ -658,6 +682,10 @@ variables. Supported values for `OTEL_EXPORTER_OTLP_PROTOCOL` are: - `http/protobuf` (default): Export using Protobuf over HTTP to the configured endpoint. - `http/json`: Export using JSON over HTTP to the configured endpoint. +- `grpc`: Export using gRPC (Protobuf over HTTP/2). Available in Deno 2.8+. + Useful for collectors that only accept gRPC, such as Azure Container Apps' + managed OpenTelemetry agent. The default OTLP gRPC port is `4317`, so you + typically also set `OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317`. - `console`: Print spans, logs, and metrics to stderr in a human-readable text format. This is useful for debugging and testing instrumentation without running an OTLP collector. When using `console`, no endpoint configuration is @@ -771,8 +799,8 @@ limitations to be aware of: - Metric exemplars are not supported. - Custom log streams (e.g. logs other than `console.log` and `console.error`) are not supported. -- The supported exporters are OTLP (`http/protobuf`, `http/json`) and `console`. - Other exporters and protocols such as `grpc` are not supported. +- The supported exporters are OTLP (`http/protobuf`, `http/json`, `grpc`) and + `console`. Other exporter formats are not supported. - Metrics from observable (asynchronous) meters are not collected on process exit/crash, so the last value of metrics may not be exported. Synchronous metrics are exported on process exit/crash. diff --git a/runtime/fundamentals/security.md b/runtime/fundamentals/security.md index f739072be..5fe529e69 100644 --- a/runtime/fundamentals/security.md +++ b/runtime/fundamentals/security.md @@ -17,6 +17,10 @@ major difference from Node, where dependencies are automatically granted full access to all system I/O, potentially introducing hidden vulnerabilities into your project. +To complement the runtime sandbox, Deno also ships +[`deno audit`](/runtime/reference/cli/audit/) for scanning your dependencies +against vulnerability databases — useful as a CI gate. + Before using Deno to run completely untrusted code, read the [section on executing untrusted code](#executing-untrusted-code) below. @@ -99,10 +103,11 @@ By default, Deno will not generate a stack trace for permission requests as it comes with a hit to performance. Users can enable stack traces with the `DENO_TRACE_PERMISSIONS` environment variable to `1`. -Deno can also generate an audit log of all accessed permissions; this can be -achieved using the `DENO_AUDIT_PERMISSIONS` environment variable to a path. This -works regardless if permissions are allowed or not. The output is in JSONL -format, where each line is an object with the following keys: +Deno can also generate an audit log of all accessed permissions, regardless of +whether the access was allowed or denied. + +Set `DENO_AUDIT_PERMISSIONS` to a **file path** to write JSONL — each line is an +object with the following keys: - `v`: the version of the format - `datetime`: when the permission was accessed, in RFC 3339 format @@ -115,7 +120,24 @@ A schema for this can be found in In addition, this env var can be combined with the above-mentioned `DENO_TRACE_PERMISSIONS`, which then adds a new `stack` field to the entries -which is an array contain all the stack trace frames. +which is an array containing all the stack trace frames. + +You can also set `DENO_AUDIT_PERMISSIONS=otel` to emit each access as an +OpenTelemetry **log record** instead of writing to a file. The records are sent +to whichever exporter you have configured via +[`OTEL_DENO`](/runtime/fundamentals/open_telemetry/) and carry these attributes: + +- `deno.permission.type` +- `deno.permission.value` +- `deno.permission.stack` (if `DENO_TRACE_PERMISSIONS` is also set) + +This is the recommended setup if you already collect OpenTelemetry data — the +permission audit lands next to your traces and metrics so you can correlate it +with request handling. + +```sh +OTEL_DENO=true DENO_AUDIT_PERMISSIONS=otel deno run -A main.ts +``` ### Configuration file diff --git a/runtime/fundamentals/testing.md b/runtime/fundamentals/testing.md index 8acadf0ac..5a64bbe3f 100644 --- a/runtime/fundamentals/testing.md +++ b/runtime/fundamentals/testing.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-02-03 +last_modified: 2026-05-20 title: "Testing" description: "A guide to Deno's testing capabilities. Learn about the built-in test runner, assertions, mocking, coverage reporting, snapshot testing, and how to write effective tests for your Deno applications." oldUrl: @@ -118,6 +118,28 @@ Deno.test("database operations", async (t) => { }); ``` +## Timeouts + +You can set a maximum duration for individual tests using the `timeout` option. +If a test exceeds its deadline it is marked as failed. Both asynchronous hangs +(a promise that never resolves) and synchronous hot loops (`while (true) {}`) +are caught. + +```ts +Deno.test({ + name: "completes within deadline", + timeout: 5000, // 5 seconds + async fn() { + const response = await fetch("https://example.com"); + await response.body?.cancel(); + }, +}); +``` + +If a test times out the next test in the same file still runs normally. + +Setting `timeout` to `0` or omitting it means the test runs without a deadline. + ## Test Hooks Deno provides test hooks that allow you to run setup and teardown code before @@ -603,16 +625,18 @@ const response = await fetch("https://example.com"); await response.body?.cancel(); // <- Always cancel the body when you are done with it, if you didn't consume it otherwise ``` -This sanitizer is enabled by default, but can be disabled in this test with -`sanitizeResources: false`: +As of Deno 2.8 this sanitizer is **off by default**. Opt in with +`sanitizeResources: true`, or with one of the global mechanisms described in +[Enabling sanitizers globally](#enabling-sanitizers-globally). ```ts Deno.test({ - name: "leaky resource test", + name: "no leaks allowed", async fn() { - await Deno.open("hello.txt"); + using file = await Deno.open("hello.txt"); + // ... }, - sanitizeResources: false, + sanitizeResources: true, }); ``` @@ -635,22 +659,61 @@ Deno.test({ }); ``` -This sanitizer is enabled by default, but can be disabled with -`sanitizeOps: false`: +As of Deno 2.8 this sanitizer is **off by default**. Opt in with +`sanitizeOps: true`, or with one of the global mechanisms described below. ```ts Deno.test({ - name: "leaky operation test", - fn() { - crypto.subtle.digest( - "SHA-256", - new TextEncoder().encode("a".repeat(100000000)), - ); + name: "no leaked ops allowed", + async fn() { + await someAsyncWork(); }, - sanitizeOps: false, + sanitizeOps: true, }); ``` +### Enabling sanitizers globally + +If you want the pre-2.8 behavior — resource and op sanitizers on for every test +— you can re-enable them at any of four scopes. Higher-precedence settings +override lower ones. + +1. **Per-test** (highest precedence): + + ```ts + Deno.test({ + name: "strict", + sanitizeOps: true, + sanitizeResources: true, + fn() {/* … */}, + }); + ``` + +2. **Per-module** with + [`Deno.test.sanitizer()`](/api/deno/~/Deno.test.sanitizer): + + ```ts + Deno.test.sanitizer({ ops: true, resources: true }); + + Deno.test("uses module-level sanitizers", () => {/* … */}); + ``` + +3. **CLI flags**: `--sanitize-ops` and `--sanitize-resources`. + +4. **Environment variables**: `DENO_TEST_SANITIZE_OPS=1` and + `DENO_TEST_SANITIZE_RESOURCES=1`. + +5. **`deno.json`** (lowest precedence): + + ```jsonc + { + "test": { + "sanitizeOps": true, + "sanitizeResources": true + } + } + ``` + ### Exit sanitizer The exit sanitizer ensures that tested code doesn’t call diff --git a/runtime/fundamentals/workspaces.md b/runtime/fundamentals/workspaces.md index 0dc763d4a..f21503757 100644 --- a/runtime/fundamentals/workspaces.md +++ b/runtime/fundamentals/workspaces.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-04-16 +last_modified: 2026-05-20 title: "Workspaces and monorepos" description: "A guide to managing workspaces and monorepos in Deno. Learn about workspace configuration, package management, dependency resolution, and how to structure multi-package projects effectively." oldUrl: /runtime/manual/basics/workspaces @@ -663,6 +663,115 @@ This approach allows you to: 3. Test and develop interdependent modules together 4. Gradually migrate monolithic codebases to modular architecture +## Centralized dependency versions with `catalog:` + +When several workspace members depend on the same npm package, keeping their +versions in sync usually means editing every member's `package.json` whenever +you bump a version. The `catalog:` protocol — added in Deno 2.8 and compatible +with the equivalent feature in pnpm, Bun, and Yarn — lets the workspace root +declare a single version requirement, and each member references it by name from +its `package.json` dependencies. (The `catalog:` specifier itself is only read +from `package.json` files; the catalog definition can live in either `deno.json` +or `package.json` at the workspace root.) + +Define a catalog in the root `deno.json`: + +```jsonc title="deno.json" +{ + "workspace": ["./packages/a", "./packages/b"], + "catalog": { + "react": "^18.3.0", + "react-dom": "^18.3.0", + "chalk": "^5.3.0" + } +} +``` + +A member references the entry with `catalog:` (the default catalog): + +```json title="packages/a/package.json" +{ + "dependencies": { + "react": "catalog:", + "react-dom": "catalog:" + } +} +``` + +To bump everyone to a new React version, edit the catalog once. + +### Named catalogs + +Use the plural `catalogs` field when different members need different versions +of the same package — for example, while migrating between major versions: + +```jsonc title="deno.json" +{ + "workspace": ["./packages/a", "./packages/b"], + "catalogs": { + "react18": { + "react": "^18.3.0", + "react-dom": "^18.3.0" + }, + "react19": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + } +} +``` + +Members select a catalog by name: + +```json title="packages/a/package.json" +{ + "dependencies": { + "react": "catalog:react18", + "react-dom": "catalog:react18" + } +} +``` + +```json title="packages/b/package.json" +{ + "dependencies": { + "react": "catalog:react19", + "react-dom": "catalog:react19" + } +} +``` + +`catalog:` (with no name) and `catalog:default` are equivalent and resolve to +the singular `catalog` field. + +### Catalogs in `package.json` + +Catalogs can also live in the root `package.json`, which keeps configuration +together for projects that haven't moved to `deno.json`: + +```json title="package.json" +{ + "catalog": { + "react": "^19.0.0" + }, + "catalogs": { + "testing": { + "vitest": "^2.0.0" + } + } +} +``` + +If both `deno.json` and `package.json` define catalogs at the workspace root, +`package.json` wins entirely — the two are not merged. + +### Restrictions + +- Catalogs are root-only. Defining `catalog` or `catalogs` inside a workspace + member emits a diagnostic. +- Members must reference a catalog name that exists. A missing entry produces a + resolution error during install or run. + ## Using workspace protocol in package.json Deno supports workspace protocol specifiers in `package.json` files. These are diff --git a/runtime/getting_started/first_project.md b/runtime/getting_started/first_project.md index c00a58380..665db678c 100644 --- a/runtime/getting_started/first_project.md +++ b/runtime/getting_started/first_project.md @@ -35,11 +35,12 @@ my_project A `deno.json` file is created to [configure your project](/runtime/fundamentals/configuration/), and two -TypeScript files are created; `main.ts` and `main_test.ts`. The `main.ts` file -is where you'll write your application code, on initial creation it will contain -a simple program which adds two numbers together. The `main_test.ts` file is -where you can write tests, initially it will contain a test for your addition -program. +TypeScript files are created; `main.ts` and `main_test.ts`. As of Deno 2.8 the +`main.ts` file contains a small HTTP server built on +[`Deno.serve`](/api/deno/~/Deno.serve) — it shows off Deno's built-in HTTP +server, `Response.json()`, and TypeScript working out of the box. The handler is +exported and guarded by `import.meta.main`, so `main_test.ts` can import and +call it directly without binding to a port. ## Run your project @@ -47,9 +48,11 @@ You can run this program with the following command: ```bash $ deno main.ts -Add 2 + 3 = 5 +Listening on http://localhost:8000/ ``` +Open the URL in your browser to see the response. + ## Run your tests Deno has a [built in test runner](/runtime/fundamentals/testing/). You can write @@ -58,10 +61,11 @@ your new project with: ```bash $ deno test -running 1 test from ./main_test.ts -addTest ... ok (1ms) +running 2 tests from ./main_test.ts +handler returns hello ... ok (1ms) +handler returns 404 for unknown route ... ok (1ms) -ok | 1 passed | 0 failed (3ms) +ok | 2 passed | 0 failed (3ms) ``` Now that you have a basic project set up you can start building your diff --git a/runtime/reference/cli/_commands_reference.json b/runtime/reference/cli/_commands_reference.json index 2fbf5a5ca..645ca0677 100644 --- a/runtime/reference/cli/_commands_reference.json +++ b/runtime/reference/cli/_commands_reference.json @@ -130,7 +130,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -224,6 +224,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -678,7 +687,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -772,6 +781,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -1147,7 +1165,7 @@ }, { "name": "add", - "about": "Add dependencies to your configuration file.\n \u001b[38;5;245mdeno add jsr:@std/path\u001b[39m\n\nYou can also add npm packages:\n \u001b[38;5;245mdeno add npm:react\u001b[39m\n\nOr multiple dependencies at once:\n \u001b[38;5;245mdeno add jsr:@std/path jsr:@std/assert npm:chalk\u001b[39m", + "about": "Add dependencies to your configuration file.\n \u001b[38;5;245mdeno add express\u001b[39m\n\nUnprefixed packages default to npm. Use jsr: prefix for jsr packages:\n \u001b[38;5;245mdeno add jsr:@std/path\u001b[39m\n\nOr multiple dependencies at once:\n \u001b[38;5;245mdeno add express jsr:@std/path\u001b[39m", "args": [ { "name": "packages", @@ -1217,7 +1235,7 @@ "short": null, "long": "npm", "required": false, - "help": "assume unprefixed package names are npm packages", + "help": "assume unprefixed package names are npm packages (default)", "help_heading": null, "usage": "--npm" }, @@ -1238,6 +1256,15 @@ "help": "Save exact version without the caret (^)", "help_heading": null, "usage": "--save-exact" + }, + { + "name": "package-json", + "short": null, + "long": "package-json", + "required": false, + "help": "Force using package.json for dependency management instead of deno.json", + "help_heading": null, + "usage": "--package-json" } ], "subcommands": [], @@ -1318,6 +1345,15 @@ "help": "Ignore advisories matching the given CVE IDs", "help_heading": null, "usage": "--ignore " + }, + { + "name": "fix", + "short": null, + "long": "fix", + "required": false, + "help": "Automatically fix vulnerabilities by upgrading packages", + "help_heading": null, + "usage": "--fix" } ], "subcommands": [], @@ -1371,6 +1407,15 @@ "help": "Install only updating the lockfile", "help_heading": null, "usage": "--lockfile-only" + }, + { + "name": "package-json", + "short": null, + "long": "package-json", + "required": false, + "help": "Force using package.json for dependency management instead of deno.json", + "help_heading": null, + "usage": "--package-json" } ], "subcommands": [], @@ -1484,7 +1529,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -1578,6 +1623,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -1973,6 +2027,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -2341,6 +2404,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -2606,7 +2678,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -2691,6 +2763,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -2915,6 +2996,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -3036,7 +3126,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -3130,6 +3220,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -3974,7 +4073,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -4068,6 +4167,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -4812,6 +4920,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -4845,7 +4962,7 @@ }, { "name": "install", - "about": "Installs dependencies either in the local project or globally to a bin directory.\n\n\u001b[32mLocal installation\u001b[39m\n\nAdd dependencies to the local project's configuration (\u001b[38;5;245mdeno.json / package.json\u001b[39m) and installs them\nin the package cache. If no dependency is specified, installs all dependencies listed in the config file.\nIf the \u001b[38;5;245m--entrypoint\u001b[39m flag is passed, installs the dependencies of the specified entrypoint(s).\n\n \u001b[38;5;245mdeno install\u001b[39m\n \u001b[38;5;245mdeno install jsr:@std/bytes\u001b[39m\n \u001b[38;5;245mdeno install npm:chalk\u001b[39m\n \u001b[38;5;245mdeno install --entrypoint entry1.ts entry2.ts\u001b[39m\n\n\u001b[32mGlobal installation\u001b[39m\n\nIf the \u001b[1m--global\u001b[22m flag is set, installs a script as an executable in the installation root's bin directory.\n\n \u001b[38;5;245mdeno install --global --allow-net --allow-read jsr:@std/http/file-server\u001b[39m\n \u001b[38;5;245mdeno install -g https://examples.deno.land/color-logging.ts\u001b[39m\n\nTo change the executable name, use \u001b[36m-n\u001b[39m/\u001b[36m--name\u001b[39m:\n \u001b[38;5;245mdeno install -g --allow-net --allow-read -n serve jsr:@std/http/file-server\u001b[39m\n\nThe executable name is inferred by default:\n - Attempt to take the file stem of the URL path. The above example would\n become \u001b[38;5;245mfile_server\u001b[39m.\n - If the file stem is something generic like \u001b[38;5;245mmain\u001b[39m, \u001b[38;5;245mmod\u001b[39m, \u001b[38;5;245mindex\u001b[39m or \u001b[38;5;245mcli\u001b[39m,\n and the path has no parent, take the file name of the parent path. Otherwise\n settle with the generic name.\n - If the resulting name has an \u001b[38;5;245m@...\u001b[39m suffix, strip it.\n\nTo change the installation root, use \u001b[36m--root\u001b[39m:\n \u001b[38;5;245mdeno install -g --allow-net --allow-read --root /usr/local jsr:@std/http/file-server\u001b[39m\n\nThe installation root is determined, in order of precedence:\n - \u001b[38;5;245m--root\u001b[39m option\n - \u001b[38;5;245mDENO_INSTALL_ROOT\u001b[39m environment variable\n - \u001b[38;5;245m$HOME/.deno\u001b[39m\n\nThese must be added to the path manually if required.", + "about": "Installs dependencies either in the local project or globally to a bin directory.\n\n\u001b[32mLocal installation\u001b[39m\n\nAdd dependencies to the local project's configuration (\u001b[38;5;245mdeno.json / package.json\u001b[39m) and installs them\nin the package cache. If no dependency is specified, installs all dependencies listed in the config file.\nIf the \u001b[38;5;245m--entrypoint\u001b[39m flag is passed, installs the dependencies of the specified entrypoint(s).\n\n \u001b[38;5;245mdeno install\u001b[39m\n \u001b[38;5;245mdeno install express\u001b[39m\n \u001b[38;5;245mdeno install jsr:@std/bytes\u001b[39m\n \u001b[38;5;245mdeno install --entrypoint entry1.ts entry2.ts\u001b[39m\n\n\u001b[32mGlobal installation\u001b[39m\n\nIf the \u001b[1m--global\u001b[22m flag is set, installs a script as an executable in the installation root's bin directory.\n\n \u001b[38;5;245mdeno install --global --allow-net --allow-read jsr:@std/http/file-server\u001b[39m\n \u001b[38;5;245mdeno install -g https://examples.deno.land/color-logging.ts\u001b[39m\n\nTo change the executable name, use \u001b[36m-n\u001b[39m/\u001b[36m--name\u001b[39m:\n \u001b[38;5;245mdeno install -g --allow-net --allow-read -n serve jsr:@std/http/file-server\u001b[39m\n\nThe executable name is inferred by default:\n - Attempt to take the file stem of the URL path. The above example would\n become \u001b[38;5;245mfile_server\u001b[39m.\n - If the file stem is something generic like \u001b[38;5;245mmain\u001b[39m, \u001b[38;5;245mmod\u001b[39m, \u001b[38;5;245mindex\u001b[39m or \u001b[38;5;245mcli\u001b[39m,\n and the path has no parent, take the file name of the parent path. Otherwise\n settle with the generic name.\n - If the resulting name has an \u001b[38;5;245m@...\u001b[39m suffix, strip it.\n\nTo change the installation root, use \u001b[36m--root\u001b[39m:\n \u001b[38;5;245mdeno install -g --allow-net --allow-read --root /usr/local jsr:@std/http/file-server\u001b[39m\n\nThe installation root is determined, in order of precedence:\n - \u001b[38;5;245m--root\u001b[39m option\n - \u001b[38;5;245mDENO_INSTALL_ROOT\u001b[39m environment variable\n - \u001b[38;5;245m$HOME/.deno\u001b[39m\n\nThese must be added to the path manually if required.", "args": [ { "name": "unstable-bare-node-builtins", @@ -4951,7 +5068,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -5045,6 +5162,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -5329,7 +5455,7 @@ "short": null, "long": "npm", "required": false, - "help": "assume unprefixed package names are npm packages", + "help": "assume unprefixed package names are npm packages (default)", "help_heading": null, "usage": "--npm" }, @@ -5361,200 +5487,442 @@ "usage": "--lockfile-only" }, { - "name": "unstable", - "short": null, - "long": "unstable", - "required": false, - "help": "The `--unstable` flag has been deprecated. Use granular `--unstable-*` flags instead", - "help_heading": "Unstable options", - "usage": "--unstable" - } - ], - "subcommands": [], - "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno install\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[cmd]...\u001b[0m \u001b[32m[--\u001b[0m \u001b[32m[SCRIPT_ARG]...\u001b[0m\u001b[32m]\u001b[0m" - }, - { - "name": "json_reference", - "about": null, - "args": [], - "subcommands": [], - "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno json_reference\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" - }, - { - "name": "jupyter", - "about": "Deno kernel for Jupyter notebooks", - "args": [ - { - "name": "install", + "name": "package-json", "short": null, - "long": "install", + "long": "package-json", "required": false, - "help": "Install a kernelspec", + "help": "Force using package.json for dependency management instead of deno.json", "help_heading": null, - "usage": "--install" + "usage": "--package-json" }, { - "name": "name", - "short": "n", - "long": "name", + "name": "os", + "short": null, + "long": "os", "required": false, - "help": "Set a name for the kernel (defaults to 'deno'). \u001b[38;5;245mUseful when maintaing multiple Deno kernels.\u001b[39m", + "help": "Target OS for npm package installation (e.g., linux, darwin, win32)", "help_heading": null, - "usage": "--name " + "usage": "--os " }, { - "name": "display", - "short": "d", - "long": "display", + "name": "arch", + "short": null, + "long": "arch", "required": false, - "help": "Set a display name for the kernel (defaults to 'Deno'). \u001b[38;5;245mUseful when maintaing multiple Deno kernels.\u001b[39m", + "help": "Target architecture for npm package installation (e.g., x64, arm64)", "help_heading": null, - "usage": "--display " + "usage": "--arch " }, { - "name": "force", + "name": "prod", "short": null, - "long": "force", + "long": "prod", "required": false, - "help": "Force installation of a kernel, overwriting previously existing kernelspec", + "help": "Only install production dependencies (excludes devDependencies)", "help_heading": null, - "usage": "--force" + "usage": "--prod" }, { - "name": "kernel", + "name": "skip-types", "short": null, - "long": "kernel", + "long": "skip-types", "required": false, - "help": "Start the kernel", + "help": "Exclude @types/* packages from installation.\n\u001b[33mBe careful, as it uses a name-based heuristic and may skip packages that ship runtime code.\u001b[39m", "help_heading": null, - "usage": "--kernel" + "usage": "--skip-types" }, { - "name": "conn", + "name": "unstable", "short": null, - "long": "conn", + "long": "unstable", "required": false, - "help": "Path to JSON file describing connection parameters, provided by Jupyter", - "help_heading": null, - "usage": "--conn " + "help": "The `--unstable` flag has been deprecated. Use granular `--unstable-*` flags instead", + "help_heading": "Unstable options", + "usage": "--unstable" } ], "subcommands": [], - "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno jupyter\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno install\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[cmd]...\u001b[0m \u001b[32m[--\u001b[0m \u001b[32m[SCRIPT_ARG]...\u001b[0m\u001b[32m]\u001b[0m" }, { - "name": "approve-scripts", - "about": "Approve npm lifecycle scripts for installed dependencies.", + "name": "ci", + "about": "Install dependencies in a clean, reproducible way for CI environments.\n\nSimilar to \u001b[38;5;245mnpm ci\u001b[39m: requires a \u001b[38;5;245mdeno.lock\u001b[39m file, removes any existing \u001b[38;5;245mnode_modules\u001b[39m\ndirectory, and then installs strictly from the lockfile. Errors if \u001b[38;5;245mdeno.lock\u001b[39m\nis missing or out of date with the config file.\n\n \u001b[38;5;245mdeno ci\u001b[39m\n \u001b[38;5;245mdeno ci --prod\u001b[39m", "args": [ { - "name": "packages", + "name": "unstable-bare-node-builtins", "short": null, - "long": null, + "long": "unstable-bare-node-builtins", "required": false, - "help": "Packages to approve (npm specifiers). When omitted, you will be prompted to select from installed packages with lifecycle scripts.", - "help_heading": null, - "usage": "[packages]..." + "help": "Enable unstable bare node builtins feature", + "help_heading": "Unstable options", + "usage": "--unstable-bare-node-builtins" }, { - "name": "lockfile-only", + "name": "unstable-bundle", "short": null, - "long": "lockfile-only", + "long": "unstable-bundle", "required": false, - "help": "Install only updating the lockfile", - "help_heading": null, - "usage": "--lockfile-only" - } - ], - "subcommands": [], - "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno approve-scripts\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[packages]...\u001b[0m" - }, - { - "name": "uninstall", - "about": "Uninstalls a dependency or an executable script in the installation root's bin directory.\n \u001b[38;5;245mdeno uninstall @std/dotenv chalk\u001b[39m\n \u001b[38;5;245mdeno uninstall --global file_server\u001b[39m\n\nTo change the installation root, use \u001b[36m--root\u001b[39m flag:\n \u001b[38;5;245mdeno uninstall --global --root /usr/local serve\u001b[39m\n\nThe installation root is determined, in order of precedence:\n - \u001b[38;5;245m--root\u001b[39m option\n - \u001b[38;5;245mDENO_INSTALL_ROOT\u001b[39m environment variable\n - \u001b[38;5;245m$HOME/.deno\u001b[39m", - "args": [ + "help": "Enable unstable bundle runtime API", + "help_heading": "Unstable options", + "usage": "--unstable-bundle" + }, { - "name": "name-or-package", + "name": "unstable-cron", "short": null, - "long": null, + "long": "unstable-cron", "required": false, - "help": null, - "help_heading": null, - "usage": "[name-or-package]" + "help": "Enable unstable `Deno.cron` API", + "help_heading": "Unstable options", + "usage": "--unstable-cron" }, { - "name": "root", + "name": "unstable-detect-cjs", "short": null, - "long": "root", + "long": "unstable-detect-cjs", "required": false, - "help": "Installation root", - "help_heading": null, - "usage": "--root " + "help": "Treats ambiguous .js, .jsx, .ts, .tsx files as CommonJS modules in more cases", + "help_heading": "Unstable options", + "usage": "--unstable-detect-cjs" }, { - "name": "global", - "short": "g", - "long": "global", + "name": "unstable-kv", + "short": null, + "long": "unstable-kv", "required": false, - "help": "Remove globally installed package or module", - "help_heading": null, - "usage": "--global" + "help": "Enable unstable KV APIs", + "help_heading": "Unstable options", + "usage": "--unstable-kv" }, { - "name": "additional-packages", + "name": "unstable-lazy-dynamic-imports", "short": null, - "long": null, + "long": "unstable-lazy-dynamic-imports", "required": false, - "help": "List of additional packages to remove", - "help_heading": null, - "usage": "[additional-packages]..." + "help": "Lazily loads statically analyzable dynamic imports when not running with type checking. Warning: This may change the order of semver specifier resolution.", + "help_heading": "Unstable options", + "usage": "--unstable-lazy-dynamic-imports" }, { - "name": "lock", + "name": "unstable-lockfile-v5", "short": null, - "long": "lock", + "long": "unstable-lockfile-v5", "required": false, - "help": "Check the specified lock file. (If value is not provided, defaults to \"./deno.lock\")", - "help_heading": "Dependency management options", - "usage": "--lock []" + "help": "Enable unstable lockfile v5", + "help_heading": "Unstable options", + "usage": "--unstable-lockfile-v5" }, { - "name": "no-lock", + "name": "unstable-net", "short": null, - "long": "no-lock", + "long": "unstable-net", "required": false, - "help": "Disable auto discovery of the lock file", - "help_heading": "Dependency management options", - "usage": "--no-lock" + "help": "enable unstable net APIs", + "help_heading": "Unstable options", + "usage": "--unstable-net" }, { - "name": "frozen", + "name": "unstable-no-legacy-abort", "short": null, - "long": "frozen", + "long": "unstable-no-legacy-abort", "required": false, - "help": "Error out if lockfile is out of date", - "help_heading": "Dependency management options", - "usage": "--frozen[=]" + "help": "Enable abort signal in Deno.serve without legacy behavior. This will not abort the server when the request is handled successfully.", + "help_heading": "Unstable options", + "usage": "--unstable-no-legacy-abort" }, { - "name": "lockfile-only", + "name": "unstable-node-globals", "short": null, - "long": "lockfile-only", + "long": "unstable-node-globals", "required": false, - "help": "Install only updating the lockfile", - "help_heading": null, - "usage": "--lockfile-only" - } - ], - "subcommands": [], - "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno uninstall\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[name-or-package]\u001b[0m \u001b[32m[additional-packages]...\u001b[0m" - }, - { - "name": "outdated", - "about": "Find and update outdated dependencies.\nBy default, outdated dependencies are only displayed.\n\nDisplay outdated dependencies:\n \u001b[38;5;245mdeno outdated\u001b[39m\n \u001b[38;5;245mdeno outdated --compatible\u001b[39m\n\nUpdate dependencies to the latest semver compatible versions:\n \u001b[38;5;245mdeno outdated --update\u001b[39m\nUpdate dependencies to the latest versions, ignoring semver requirements:\n \u001b[38;5;245mdeno outdated --update --latest\u001b[39m\n\nFilters can be used to select which packages to act on. Filters can include wildcards (*) to match multiple packages.\n \u001b[38;5;245mdeno outdated --update --latest \"@std/*\"\u001b[39m\n \u001b[38;5;245mdeno outdated --update --latest \"react*\"\u001b[39m\nNote that filters act on their aliases configured in deno.json / package.json, not the actual package names:\n Given \"foobar\": \"npm:react@17.0.0\" in deno.json or package.json, the filter \"foobar\" would update npm:react to\n the latest version.\n \u001b[38;5;245mdeno outdated --update --latest foobar\u001b[39m\nFilters can be combined, and negative filters can be used to exclude results:\n \u001b[38;5;245mdeno outdated --update --latest \"@std/*\" \"!@std/fmt*\"\u001b[39m\n\nSpecific version requirements to update to can be specified:\n \u001b[38;5;245mdeno outdated --update @std/fmt@^1.0.2\u001b[39m\n", - "args": [ - { - "name": "filters", - "short": null, + "help": "Prefer Node.js globals over Deno globals - currently this refers to `setTimeout` and `setInterval` APIs.", + "help_heading": "Unstable options", + "usage": "--unstable-node-globals" + }, + { + "name": "unstable-npm-lazy-caching", + "short": null, + "long": "unstable-npm-lazy-caching", + "required": false, + "help": "Enable unstable lazy caching of npm dependencies, downloading them only as needed (disabled: all npm packages in package.json are installed on startup; enabled: only npm packages that are actually referenced in an import are installed", + "help_heading": "Unstable options", + "usage": "--unstable-npm-lazy-caching" + }, + { + "name": "unstable-raw-imports", + "short": null, + "long": "unstable-raw-imports", + "required": false, + "help": "Enable unstable 'bytes' imports.", + "help_heading": "Unstable options", + "usage": "--unstable-raw-imports" + }, + { + "name": "unstable-sloppy-imports", + "short": null, + "long": "unstable-sloppy-imports", + "required": false, + "help": "Enable unstable resolving of specifiers by extension probing, .js to .ts, and directory probing", + "help_heading": "Unstable options", + "usage": "--unstable-sloppy-imports" + }, + { + "name": "unstable-tsgo", + "short": null, + "long": "unstable-tsgo", + "required": false, + "help": "Enable unstable TypeScript Go integration", + "help_heading": "Unstable options", + "usage": "--unstable-tsgo" + }, + { + "name": "unstable-unsafe-proto", + "short": null, + "long": "unstable-unsafe-proto", + "required": false, + "help": "Enable unsafe __proto__ support. This is a security risk.", + "help_heading": "Unstable options", + "usage": "--unstable-unsafe-proto" + }, + { + "name": "unstable-webgpu", + "short": null, + "long": "unstable-webgpu", + "required": false, + "help": "Enable unstable WebGPU APIs", + "help_heading": "Unstable options", + "usage": "--unstable-webgpu" + }, + { + "name": "unstable-worker-options", + "short": null, + "long": "unstable-worker-options", + "required": false, + "help": "Enable unstable Web Worker APIs", + "help_heading": "Unstable options", + "usage": "--unstable-worker-options" + }, + { + "name": "prod", + "short": null, + "long": "prod", + "required": false, + "help": "Only install production dependencies (excludes devDependencies)", + "help_heading": null, + "usage": "--prod" + }, + { + "name": "skip-types", + "short": null, + "long": "skip-types", + "required": false, + "help": "Exclude @types/* packages from installation.\n\u001b[33mBe careful, as it uses a name-based heuristic and may skip packages that ship runtime code.\u001b[39m", + "help_heading": null, + "usage": "--skip-types" + }, + { + "name": "unstable", + "short": null, + "long": "unstable", + "required": false, + "help": "The `--unstable` flag has been deprecated. Use granular `--unstable-*` flags instead", + "help_heading": "Unstable options", + "usage": "--unstable" + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno ci\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, + { + "name": "json_reference", + "about": null, + "args": [], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno json_reference\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, + { + "name": "jupyter", + "about": "Deno kernel for Jupyter notebooks", + "args": [ + { + "name": "install", + "short": null, + "long": "install", + "required": false, + "help": "Install a kernelspec", + "help_heading": null, + "usage": "--install" + }, + { + "name": "name", + "short": "n", + "long": "name", + "required": false, + "help": "Set a name for the kernel (defaults to 'deno'). \u001b[38;5;245mUseful when maintaing multiple Deno kernels.\u001b[39m", + "help_heading": null, + "usage": "--name " + }, + { + "name": "display", + "short": "d", + "long": "display", + "required": false, + "help": "Set a display name for the kernel (defaults to 'Deno'). \u001b[38;5;245mUseful when maintaing multiple Deno kernels.\u001b[39m", + "help_heading": null, + "usage": "--display " + }, + { + "name": "force", + "short": null, + "long": "force", + "required": false, + "help": "Force installation of a kernel, overwriting previously existing kernelspec", + "help_heading": null, + "usage": "--force" + }, + { + "name": "kernel", + "short": null, + "long": "kernel", + "required": false, + "help": "Start the kernel", + "help_heading": null, + "usage": "--kernel" + }, + { + "name": "conn", + "short": null, + "long": "conn", + "required": false, + "help": "Path to JSON file describing connection parameters, provided by Jupyter", + "help_heading": null, + "usage": "--conn " + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno jupyter\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, + { + "name": "approve-scripts", + "about": "Approve npm lifecycle scripts for installed dependencies.", + "args": [ + { + "name": "packages", + "short": null, + "long": null, + "required": false, + "help": "Packages to approve (npm specifiers). When omitted, you will be prompted to select from installed packages with lifecycle scripts.", + "help_heading": null, + "usage": "[packages]..." + }, + { + "name": "lockfile-only", + "short": null, + "long": "lockfile-only", + "required": false, + "help": "Install only updating the lockfile", + "help_heading": null, + "usage": "--lockfile-only" + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno approve-scripts\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[packages]...\u001b[0m" + }, + { + "name": "uninstall", + "about": "Uninstalls a dependency or an executable script in the installation root's bin directory.\n \u001b[38;5;245mdeno uninstall @std/dotenv chalk\u001b[39m\n \u001b[38;5;245mdeno uninstall --global file_server\u001b[39m\n\nTo change the installation root, use \u001b[36m--root\u001b[39m flag:\n \u001b[38;5;245mdeno uninstall --global --root /usr/local serve\u001b[39m\n\nThe installation root is determined, in order of precedence:\n - \u001b[38;5;245m--root\u001b[39m option\n - \u001b[38;5;245mDENO_INSTALL_ROOT\u001b[39m environment variable\n - \u001b[38;5;245m$HOME/.deno\u001b[39m", + "args": [ + { + "name": "name-or-package", + "short": null, + "long": null, + "required": false, + "help": null, + "help_heading": null, + "usage": "[name-or-package]" + }, + { + "name": "root", + "short": null, + "long": "root", + "required": false, + "help": "Installation root", + "help_heading": null, + "usage": "--root " + }, + { + "name": "global", + "short": "g", + "long": "global", + "required": false, + "help": "Remove globally installed package or module", + "help_heading": null, + "usage": "--global" + }, + { + "name": "additional-packages", + "short": null, + "long": null, + "required": false, + "help": "List of additional packages to remove", + "help_heading": null, + "usage": "[additional-packages]..." + }, + { + "name": "lock", + "short": null, + "long": "lock", + "required": false, + "help": "Check the specified lock file. (If value is not provided, defaults to \"./deno.lock\")", + "help_heading": "Dependency management options", + "usage": "--lock []" + }, + { + "name": "no-lock", + "short": null, + "long": "no-lock", + "required": false, + "help": "Disable auto discovery of the lock file", + "help_heading": "Dependency management options", + "usage": "--no-lock" + }, + { + "name": "frozen", + "short": null, + "long": "frozen", + "required": false, + "help": "Error out if lockfile is out of date", + "help_heading": "Dependency management options", + "usage": "--frozen[=]" + }, + { + "name": "lockfile-only", + "short": null, + "long": "lockfile-only", + "required": false, + "help": "Install only updating the lockfile", + "help_heading": null, + "usage": "--lockfile-only" + }, + { + "name": "package-json", + "short": null, + "long": "package-json", + "required": false, + "help": "Force using package.json for dependency management instead of deno.json", + "help_heading": null, + "usage": "--package-json" + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno uninstall\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[name-or-package]\u001b[0m \u001b[32m[additional-packages]...\u001b[0m" + }, + { + "name": "outdated", + "about": "Find and update outdated dependencies.\nBy default, outdated dependencies are only displayed.\n\nDisplay outdated dependencies:\n \u001b[38;5;245mdeno outdated\u001b[39m\n \u001b[38;5;245mdeno outdated --compatible\u001b[39m\n\nUpdate dependencies to the latest semver compatible versions:\n \u001b[38;5;245mdeno outdated --update\u001b[39m\nUpdate dependencies to the latest versions, ignoring semver requirements:\n \u001b[38;5;245mdeno outdated --update --latest\u001b[39m\n\nFilters can be used to select which packages to act on. Filters can include wildcards (*) to match multiple packages.\n \u001b[38;5;245mdeno outdated --update --latest \"@std/*\"\u001b[39m\n \u001b[38;5;245mdeno outdated --update --latest \"react*\"\u001b[39m\nNote that filters act on their aliases configured in deno.json / package.json, not the actual package names:\n Given \"foobar\": \"npm:react@17.0.0\" in deno.json or package.json, the filter \"foobar\" would update npm:react to\n the latest version.\n \u001b[38;5;245mdeno outdated --update --latest foobar\u001b[39m\nFilters can be combined, and negative filters can be used to exclude results:\n \u001b[38;5;245mdeno outdated --update --latest \"@std/*\" \"!@std/fmt*\"\u001b[39m\n\nSpecific version requirements to update to can be specified:\n \u001b[38;5;245mdeno outdated --update @std/fmt@^1.0.2\u001b[39m\n", + "args": [ + { + "name": "filters", + "short": null, "long": null, "required": false, "help": "Filters selecting which packages to act on. Can include wildcards (*) to match multiple packages. If a version requirement is specified, the matching packages will be updated to the given requirement.", @@ -6074,6 +6442,185 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno publish\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "pack", + "about": "Create an npm-compatible tarball from a Deno project", + "args": [ + { + "name": "unstable-bare-node-builtins", + "short": null, + "long": "unstable-bare-node-builtins", + "required": false, + "help": "Enable unstable bare node builtins feature", + "help_heading": "Unstable options", + "usage": "--unstable-bare-node-builtins" + }, + { + "name": "unstable-detect-cjs", + "short": null, + "long": "unstable-detect-cjs", + "required": false, + "help": "Treats ambiguous .js, .jsx, .ts, .tsx files as CommonJS modules in more cases", + "help_heading": "Unstable options", + "usage": "--unstable-detect-cjs" + }, + { + "name": "unstable-lazy-dynamic-imports", + "short": null, + "long": "unstable-lazy-dynamic-imports", + "required": false, + "help": "Lazily loads statically analyzable dynamic imports when not running with type checking. Warning: This may change the order of semver specifier resolution.", + "help_heading": "Unstable options", + "usage": "--unstable-lazy-dynamic-imports" + }, + { + "name": "unstable-lockfile-v5", + "short": null, + "long": "unstable-lockfile-v5", + "required": false, + "help": "Enable unstable lockfile v5", + "help_heading": "Unstable options", + "usage": "--unstable-lockfile-v5" + }, + { + "name": "unstable-npm-lazy-caching", + "short": null, + "long": "unstable-npm-lazy-caching", + "required": false, + "help": "Enable unstable lazy caching of npm dependencies, downloading them only as needed (disabled: all npm packages in package.json are installed on startup; enabled: only npm packages that are actually referenced in an import are installed", + "help_heading": "Unstable options", + "usage": "--unstable-npm-lazy-caching" + }, + { + "name": "unstable-sloppy-imports", + "short": null, + "long": "unstable-sloppy-imports", + "required": false, + "help": "Enable unstable resolving of specifiers by extension probing, .js to .ts, and directory probing", + "help_heading": "Unstable options", + "usage": "--unstable-sloppy-imports" + }, + { + "name": "unstable-tsgo", + "short": null, + "long": "unstable-tsgo", + "required": false, + "help": "Enable unstable TypeScript Go integration", + "help_heading": "Unstable options", + "usage": "--unstable-tsgo" + }, + { + "name": "output", + "short": "o", + "long": "output", + "required": false, + "help": "Output file path (defaults to -.tgz)", + "help_heading": null, + "usage": "--output " + }, + { + "name": "config", + "short": "c", + "long": "config", + "required": false, + "help": "Configure different aspects of deno including TypeScript, linting, and code formatting.\n \u001b[38;5;245mTypically the configuration file will be called `deno.json` or `deno.jsonc` and\n automatically detected; in that case this flag is not necessary.\n Docs: https://docs.deno.com/go/config\u001b[39m", + "help_heading": null, + "usage": "--config " + }, + { + "name": "no-config", + "short": null, + "long": "no-config", + "required": false, + "help": "Disable automatic loading of the configuration file", + "help_heading": null, + "usage": "--no-config" + }, + { + "name": "dry-run", + "short": null, + "long": "dry-run", + "required": false, + "help": "Show what would be packed without creating the tarball", + "help_heading": null, + "usage": "--dry-run" + }, + { + "name": "allow-slow-types", + "short": null, + "long": "allow-slow-types", + "required": false, + "help": "Skip fast-check type extraction; .d.ts files are omitted from the output", + "help_heading": null, + "usage": "--allow-slow-types" + }, + { + "name": "allow-dirty", + "short": null, + "long": "allow-dirty", + "required": false, + "help": "Allow packing if the repository has uncommitted changes", + "help_heading": null, + "usage": "--allow-dirty" + }, + { + "name": "set-version", + "short": null, + "long": "set-version", + "required": false, + "help": "Override the version in the tarball", + "help_heading": null, + "usage": "--set-version " + }, + { + "name": "no-deno-shim", + "short": null, + "long": "no-deno-shim", + "required": false, + "help": "Don't automatically add @deno/shim-deno dependency", + "help_heading": null, + "usage": "--no-deno-shim" + }, + { + "name": "no-source-maps", + "short": null, + "long": "no-source-maps", + "required": false, + "help": "Don't include source maps in the output", + "help_heading": null, + "usage": "--no-source-maps" + }, + { + "name": "files", + "short": null, + "long": null, + "required": false, + "help": "List of file patterns to include", + "help_heading": null, + "usage": "[files]..." + }, + { + "name": "ignore", + "short": null, + "long": "ignore", + "required": false, + "help": "Ignore files matching these patterns", + "help_heading": null, + "usage": "--ignore=..." + }, + { + "name": "unstable", + "short": null, + "long": "unstable", + "required": false, + "help": "The `--unstable` flag has been deprecated. Use granular `--unstable-*` flags instead", + "help_heading": "Unstable options", + "usage": "--unstable" + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno pack\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[files]...\u001b[0m" + }, { "name": "repl", "about": "Starts a read-eval-print-loop, which lets you interactively build up program state in the global context.\nIt is especially useful for quick prototyping and checking snippets of code.\n\nTypeScript is supported, however it is not type-checked, only transpiled.", @@ -6182,7 +6729,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -6285,6 +6832,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -6595,7 +7151,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -6716,6 +7272,15 @@ "help_heading": null, "usage": "--eval" }, + { + "name": "no-prefix", + "short": null, + "long": "no-prefix", + "required": false, + "help": "Disable prefixing the output of concurrently-executing tasks with the task name", + "help_heading": null, + "usage": "--no-prefix" + }, { "name": "node-modules-dir", "short": null, @@ -6725,6 +7290,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "tunnel", "short": "t", @@ -6855,7 +7429,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -6949,6 +7523,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -7165,6 +7748,24 @@ "help_heading": "Testing options", "usage": "--trace-leaks" }, + { + "name": "sanitize-ops", + "short": null, + "long": "sanitize-ops", + "required": false, + "help": "Enable the ops sanitizer, which ensures that all async ops started in a test are completed before the test ends", + "help_heading": "Testing options", + "usage": "--sanitize-ops" + }, + { + "name": "sanitize-resources", + "short": null, + "long": "sanitize-resources", + "required": false, + "help": "Enable the resources sanitizer, which ensures that all resources opened in a test are closed before the test ends", + "help_heading": "Testing options", + "usage": "--sanitize-resources" + }, { "name": "doc", "short": null, @@ -7220,121 +7821,381 @@ "usage": "--coverage[=]" }, { - "name": "coverage-raw-data-only", + "name": "coverage-raw-data-only", + "short": null, + "long": "coverage-raw-data-only", + "required": false, + "help": "Only collect raw coverage data, without generating a report", + "help_heading": "Testing options", + "usage": "--coverage-raw-data-only" + }, + { + "name": "clean", + "short": null, + "long": "clean", + "required": false, + "help": "Empty the temporary coverage profile data directory before running tests.\n \u001b[38;5;245mNote: running multiple `deno test --clean` calls in series or parallel for the same coverage directory may cause race conditions.\u001b[39m", + "help_heading": "Testing options", + "usage": "--clean" + }, + { + "name": "parallel", + "short": null, + "long": "parallel", + "required": false, + "help": "Run test modules in parallel. Parallelism defaults to the number of available CPUs or the value of the DENO_JOBS environment variable", + "help_heading": null, + "usage": "--parallel" + }, + { + "name": "files", + "short": null, + "long": null, + "required": false, + "help": "List of file names to run", + "help_heading": null, + "usage": "[files]..." + }, + { + "name": "watch", + "short": null, + "long": "watch", + "required": false, + "help": "Watch for file changes and restart process automatically.\n \u001b[38;5;245mLocal files from entry point module graph are watched by default.\n Additional paths might be watched by passing them as arguments to this flag.\u001b[39m", + "help_heading": "File watching options", + "usage": "--watch[=...]" + }, + { + "name": "watch-exclude", + "short": null, + "long": "watch-exclude", + "required": false, + "help": "Exclude provided files/patterns from watch mode", + "help_heading": "File watching options", + "usage": "--watch-exclude[=...]" + }, + { + "name": "no-clear-screen", + "short": null, + "long": "no-clear-screen", + "required": false, + "help": "Do not clear terminal screen when under watch mode", + "help_heading": "File watching options", + "usage": "--no-clear-screen" + }, + { + "name": "script_arg", + "short": null, + "long": null, + "required": false, + "help": "Script arg", + "help_heading": null, + "usage": "[SCRIPT_ARG]..." + }, + { + "name": "junit-path", + "short": null, + "long": "junit-path", + "required": false, + "help": "Write a JUnit XML test report to PATH. Use '-' to write to stdout which is the default when PATH is not provided", + "help_heading": "Testing options", + "usage": "--junit-path " + }, + { + "name": "reporter", + "short": null, + "long": "reporter", + "required": false, + "help": "Select reporter to use. Default to 'pretty'", + "help_heading": "Testing options", + "usage": "--reporter " + }, + { + "name": "hide-stacktraces", + "short": null, + "long": "hide-stacktraces", + "required": false, + "help": "Hide stack traces for errors in failure test results.", + "help_heading": null, + "usage": "--hide-stacktraces" + }, + { + "name": "env-file", + "short": null, + "long": "env-file", + "required": false, + "help": "Load environment variables from local file\n \u001b[38;5;245mOnly the first environment variable with a given key is used.\n Existing process environment variables are not overwritten, so if variables with the same names already exist in the environment, their values will be preserved.\n Where multiple declarations for the same environment variable exist in your .env file, the first one encountered is applied. This is determined by the order of the files you pass as arguments.\u001b[39m", + "help_heading": null, + "usage": "--env-file[=]" + }, + { + "name": "ext", + "short": null, + "long": "ext", + "required": false, + "help": "Set content type of the supplied file", + "help_heading": null, + "usage": "--ext " + }, + { + "name": "unstable", + "short": null, + "long": "unstable", + "required": false, + "help": "The `--unstable` flag has been deprecated. Use granular `--unstable-*` flags instead", + "help_heading": "Unstable options", + "usage": "--unstable" + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno test\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[files]...\u001b[0m \u001b[32m[--\u001b[0m \u001b[32m[SCRIPT_ARG]...\u001b[0m\u001b[32m]\u001b[0m" + }, + { + "name": "transpile", + "about": "Transpile TypeScript/JSX/TSX files to JavaScript.\n\n \u001b[38;5;245mdeno transpile main.ts\u001b[39m\n\nOutput to a specific file:\n \u001b[38;5;245mdeno transpile main.ts -o main.js\u001b[39m\n\nOutput to a directory:\n \u001b[38;5;245mdeno transpile src/*.ts --outdir dist\u001b[39m\n\nWith source maps:\n \u001b[38;5;245mdeno transpile main.ts --source-map separate\u001b[39m\n\nGenerate declaration files:\n \u001b[38;5;245mdeno transpile main.ts -o out.js --declaration\u001b[39m\n\nNote: --declaration always writes .d.ts files to disk (next to the source or in --outdir).", + "args": [ + { + "name": "unstable-bare-node-builtins", + "short": null, + "long": "unstable-bare-node-builtins", + "required": false, + "help": "Enable unstable bare node builtins feature", + "help_heading": "Unstable options", + "usage": "--unstable-bare-node-builtins" + }, + { + "name": "unstable-detect-cjs", + "short": null, + "long": "unstable-detect-cjs", + "required": false, + "help": "Treats ambiguous .js, .jsx, .ts, .tsx files as CommonJS modules in more cases", + "help_heading": "Unstable options", + "usage": "--unstable-detect-cjs" + }, + { + "name": "unstable-lazy-dynamic-imports", + "short": null, + "long": "unstable-lazy-dynamic-imports", + "required": false, + "help": "Lazily loads statically analyzable dynamic imports when not running with type checking. Warning: This may change the order of semver specifier resolution.", + "help_heading": "Unstable options", + "usage": "--unstable-lazy-dynamic-imports" + }, + { + "name": "unstable-lockfile-v5", + "short": null, + "long": "unstable-lockfile-v5", + "required": false, + "help": "Enable unstable lockfile v5", + "help_heading": "Unstable options", + "usage": "--unstable-lockfile-v5" + }, + { + "name": "unstable-npm-lazy-caching", + "short": null, + "long": "unstable-npm-lazy-caching", + "required": false, + "help": "Enable unstable lazy caching of npm dependencies, downloading them only as needed (disabled: all npm packages in package.json are installed on startup; enabled: only npm packages that are actually referenced in an import are installed", + "help_heading": "Unstable options", + "usage": "--unstable-npm-lazy-caching" + }, + { + "name": "unstable-sloppy-imports", + "short": null, + "long": "unstable-sloppy-imports", + "required": false, + "help": "Enable unstable resolving of specifiers by extension probing, .js to .ts, and directory probing", + "help_heading": "Unstable options", + "usage": "--unstable-sloppy-imports" + }, + { + "name": "unstable-tsgo", + "short": null, + "long": "unstable-tsgo", + "required": false, + "help": "Enable unstable TypeScript Go integration", + "help_heading": "Unstable options", + "usage": "--unstable-tsgo" + }, + { + "name": "import-map", + "short": null, + "long": "import-map", + "required": false, + "help": "Load import map file from local file or remote URL\n \u001b[38;5;245mDocs: https://docs.deno.com/runtime/manual/basics/import_maps\u001b[39m", + "help_heading": "Dependency management options", + "usage": "--import-map " + }, + { + "name": "no-remote", + "short": null, + "long": "no-remote", + "required": false, + "help": "Do not resolve remote modules", + "help_heading": "Dependency management options", + "usage": "--no-remote" + }, + { + "name": "no-npm", + "short": null, + "long": "no-npm", + "required": false, + "help": "Do not resolve npm modules", + "help_heading": "Dependency management options", + "usage": "--no-npm" + }, + { + "name": "node-modules-dir", + "short": null, + "long": "node-modules-dir", + "required": false, + "help": "Sets the node modules management mode for npm packages", + "help_heading": "Dependency management options", + "usage": "--node-modules-dir[=]" + }, + { + "name": "node-modules-linker", "short": null, - "long": "coverage-raw-data-only", + "long": "node-modules-linker", "required": false, - "help": "Only collect raw coverage data, without generating a report", - "help_heading": "Testing options", - "usage": "--coverage-raw-data-only" + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" }, { - "name": "clean", + "name": "vendor", "short": null, - "long": "clean", + "long": "vendor", "required": false, - "help": "Empty the temporary coverage profile data directory before running tests.\n \u001b[38;5;245mNote: running multiple `deno test --clean` calls in series or parallel for the same coverage directory may cause race conditions.\u001b[39m", - "help_heading": "Testing options", - "usage": "--clean" + "help": "Toggles local vendor folder usage for remote modules and a node_modules folder for npm packages", + "help_heading": "Dependency management options", + "usage": "--vendor[=]" }, { - "name": "parallel", + "name": "conditions", "short": null, - "long": "parallel", + "long": "conditions", "required": false, - "help": "Run test modules in parallel. Parallelism defaults to the number of available CPUs or the value of the DENO_JOBS environment variable", + "help": "Use this argument to specify custom conditions for npm package exports. You can also use DENO_CONDITIONS env var.\n\nDocs: https://docs.deno.com/go/conditional-exports", "help_heading": null, - "usage": "--parallel" + "usage": "--conditions " }, { - "name": "files", + "name": "config", + "short": "c", + "long": "config", + "required": false, + "help": "Configure different aspects of deno including TypeScript, linting, and code formatting.\n \u001b[38;5;245mTypically the configuration file will be called `deno.json` or `deno.jsonc` and\n automatically detected; in that case this flag is not necessary.\n Docs: https://docs.deno.com/go/config\u001b[39m", + "help_heading": null, + "usage": "--config " + }, + { + "name": "no-config", "short": null, - "long": null, + "long": "no-config", "required": false, - "help": "List of file names to run", + "help": "Disable automatic loading of the configuration file", "help_heading": null, - "usage": "[files]..." + "usage": "--no-config" }, { - "name": "watch", + "name": "reload", + "short": "r", + "long": "reload", + "required": false, + "help": "Reload source code cache (recompile TypeScript)\n \u001b[38;5;245mno value Reload everything\n jsr:@std/http/file-server,jsr:@std/assert/assert-equals Reloads specific modules\n npm: Reload all npm modules\n npm:chalk Reload specific npm module\u001b[39m", + "help_heading": "Dependency management options", + "usage": "--reload[=...]" + }, + { + "name": "lock", "short": null, - "long": "watch", + "long": "lock", "required": false, - "help": "Watch for file changes and restart process automatically.\n \u001b[38;5;245mLocal files from entry point module graph are watched by default.\n Additional paths might be watched by passing them as arguments to this flag.\u001b[39m", - "help_heading": "File watching options", - "usage": "--watch[=...]" + "help": "Check the specified lock file. (If value is not provided, defaults to \"./deno.lock\")", + "help_heading": "Dependency management options", + "usage": "--lock []" }, { - "name": "watch-exclude", + "name": "no-lock", "short": null, - "long": "watch-exclude", + "long": "no-lock", "required": false, - "help": "Exclude provided files/patterns from watch mode", - "help_heading": "File watching options", - "usage": "--watch-exclude[=...]" + "help": "Disable auto discovery of the lock file", + "help_heading": "Dependency management options", + "usage": "--no-lock" }, { - "name": "no-clear-screen", + "name": "frozen", "short": null, - "long": "no-clear-screen", + "long": "frozen", "required": false, - "help": "Do not clear terminal screen when under watch mode", - "help_heading": "File watching options", - "usage": "--no-clear-screen" + "help": "Error out if lockfile is out of date", + "help_heading": "Dependency management options", + "usage": "--frozen[=]" }, { - "name": "script_arg", + "name": "cert", "short": null, - "long": null, + "long": "cert", "required": false, - "help": "Script arg", + "help": "Load certificate authority from PEM encoded file", "help_heading": null, - "usage": "[SCRIPT_ARG]..." + "usage": "--cert " }, { - "name": "junit-path", + "name": "minimum-dependency-age", "short": null, - "long": "junit-path", + "long": "minimum-dependency-age", "required": false, - "help": "Write a JUnit XML test report to PATH. Use '-' to write to stdout which is the default when PATH is not provided", - "help_heading": "Testing options", - "usage": "--junit-path " + "help": "(Unstable) The age in minutes, ISO-8601 duration or RFC3339 absolute timestamp (e.g. '120' for two hours, 'P2D' for two days, '2025-09-16' for cutoff date, '2025-09-16T12:00:00+00:00' for cutoff time, '0' to disable)", + "help_heading": null, + "usage": "--minimum-dependency-age " }, { - "name": "reporter", + "name": "file", "short": null, - "long": "reporter", + "long": null, "required": false, - "help": "Select reporter to use. Default to 'pretty'", - "help_heading": "Testing options", - "usage": "--reporter " + "help": null, + "help_heading": null, + "usage": "[file]..." }, { - "name": "hide-stacktraces", + "name": "output", + "short": "o", + "long": "output", + "required": false, + "help": "Output file path (for single file transpilation)", + "help_heading": null, + "usage": "--output " + }, + { + "name": "outdir", "short": null, - "long": "hide-stacktraces", + "long": "outdir", "required": false, - "help": "Hide stack traces for errors in failure test results.", + "help": "Output directory for transpiled files", "help_heading": null, - "usage": "--hide-stacktraces" + "usage": "--outdir " }, { - "name": "env-file", + "name": "source-map", "short": null, - "long": "env-file", + "long": "source-map", "required": false, - "help": "Load environment variables from local file\n \u001b[38;5;245mOnly the first environment variable with a given key is used.\n Existing process environment variables are not overwritten, so if variables with the same names already exist in the environment, their values will be preserved.\n Where multiple declarations for the same environment variable exist in your .env file, the first one encountered is applied. This is determined by the order of the files you pass as arguments.\u001b[39m", + "help": "Source map mode: none, inline, or separate", "help_heading": null, - "usage": "--env-file[=]" + "usage": "--source-map " }, { - "name": "ext", + "name": "declaration", "short": null, - "long": "ext", + "long": "declaration", "required": false, - "help": "Set content type of the supplied file", + "help": "Generate .d.ts declaration files (requires type-checking via tsc)", "help_heading": null, - "usage": "--ext " + "usage": "--declaration" }, { "name": "unstable", @@ -7347,7 +8208,7 @@ } ], "subcommands": [], - "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno test\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[files]...\u001b[0m \u001b[32m[--\u001b[0m \u001b[32m[SCRIPT_ARG]...\u001b[0m\u001b[32m]\u001b[0m" + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno transpile\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[file]...\u001b[0m" }, { "name": "types", @@ -7525,6 +8386,86 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno upgrade\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[VERSION]...\u001b[0m" }, + { + "name": "bump-version", + "about": "Update version in the configuration file.\n \u001b[38;5;245mdeno bump-version patch\u001b[39m \u001b[38;5;245m# 1.4.6 -> 1.4.7\u001b[39m\n \u001b[38;5;245mdeno bump-version minor\u001b[39m \u001b[38;5;245m# 1.4.6 -> 1.5.0\u001b[39m\n \u001b[38;5;245mdeno bump-version major\u001b[39m \u001b[38;5;245m# 1.4.6 -> 2.0.0\u001b[39m\n \u001b[38;5;245mdeno bump-version prepatch\u001b[39m \u001b[38;5;245m# 1.4.6 -> 1.4.7-0\u001b[39m\n \u001b[38;5;245mdeno bump-version preminor\u001b[39m \u001b[38;5;245m# 1.4.6 -> 1.5.0-0\u001b[39m\n \u001b[38;5;245mdeno bump-version premajor\u001b[39m \u001b[38;5;245m# 1.4.6 -> 2.0.0-0\u001b[39m\n \u001b[38;5;245mdeno bump-version prerelease\u001b[39m \u001b[38;5;245m# 1.4.7-0 -> 1.4.7-1\u001b[39m\n\nWhen invoked at a workspace root, the same increment is applied to every\nmember package and jsr: references in the root import map are updated.\nWithout an increment, per-package bumps are derived from conventional\ncommit messages between the latest tag and the current branch and a\nrelease note is prepended to \u001b[38;5;245mReleases.md\u001b[39m.", + "args": [ + { + "name": "increment", + "short": null, + "long": null, + "required": false, + "help": "Version increment type", + "help_heading": null, + "usage": "[increment]" + }, + { + "name": "workspace", + "short": "w", + "long": "workspace", + "required": false, + "help": "Bump every package in the workspace (auto-detected at the workspace root)", + "help_heading": null, + "usage": "--workspace" + }, + { + "name": "no-workspace", + "short": null, + "long": "no-workspace", + "required": false, + "help": "Disable workspace mode and only bump the deno.json/package.json in the current directory", + "help_heading": null, + "usage": "--no-workspace" + }, + { + "name": "dry-run", + "short": null, + "long": "dry-run", + "required": false, + "help": "Print the planned changes without writing any files", + "help_heading": null, + "usage": "--dry-run" + }, + { + "name": "start", + "short": null, + "long": "start", + "required": false, + "help": "[conventional-commits mode] Git ref to start from. Default: latest tag (git describe --tags --abbrev=0)", + "help_heading": null, + "usage": "--start " + }, + { + "name": "base", + "short": null, + "long": "base", + "required": false, + "help": "[conventional-commits mode] Git ref to compare against. Default: current branch", + "help_heading": null, + "usage": "--base " + }, + { + "name": "import-map", + "short": null, + "long": "import-map", + "required": false, + "help": "Path to the import map to rewrite jsr: version constraints in. Defaults to the root deno.json (or its importMap target)", + "help_heading": null, + "usage": "--import-map " + }, + { + "name": "release-notes", + "short": null, + "long": "release-notes", + "required": false, + "help": "[conventional-commits mode] Path to the release notes file to prepend. Default: Releases.md", + "help_heading": null, + "usage": "--release-notes " + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno bump-version\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m[increment]\u001b[0m" + }, { "name": "vendor", "about": "`deno vendor` was removed in Deno 2.\n\nSee the Deno 1.x to 2.x Migration Guide for migration instructions: https://docs.deno.com/runtime/manual/advanced/migrate_deprecations", @@ -7605,6 +8546,50 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno vendor\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "why", + "about": "Show why a package is installed, displaying the dependency chain from your project's direct dependencies to the specified package.\n \u001b[38;5;245mdeno why express\u001b[39m\n\nShow why a specific version is installed\n \u001b[38;5;245mdeno why express@4.18.2\u001b[39m", + "args": [ + { + "name": "lock", + "short": null, + "long": "lock", + "required": false, + "help": "Check the specified lock file. (If value is not provided, defaults to \"./deno.lock\")", + "help_heading": "Dependency management options", + "usage": "--lock []" + }, + { + "name": "no-lock", + "short": null, + "long": "no-lock", + "required": false, + "help": "Disable auto discovery of the lock file", + "help_heading": "Dependency management options", + "usage": "--no-lock" + }, + { + "name": "frozen", + "short": null, + "long": "frozen", + "required": false, + "help": "Error out if lockfile is out of date", + "help_heading": "Dependency management options", + "usage": "--frozen[=]" + }, + { + "name": "package", + "short": null, + "long": null, + "required": true, + "help": "The package name (and optional version) to explain", + "help_heading": null, + "usage": "" + } + ], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno why\u001b[0m \u001b[32m[OPTIONS]\u001b[0m \u001b[32m\u001b[0m" + }, { "name": "x", "about": "Execute a binary from npm or jsr, like npx", @@ -7713,7 +8698,7 @@ "short": null, "long": "unstable-raw-imports", "required": false, - "help": "Enable unstable 'bytes' and 'text' imports.", + "help": "Enable unstable 'bytes' imports.", "help_heading": "Unstable options", "usage": "--unstable-raw-imports" }, @@ -7807,6 +8792,15 @@ "help_heading": "Dependency management options", "usage": "--node-modules-dir[=]" }, + { + "name": "node-modules-linker", + "short": null, + "long": "node-modules-linker", + "required": false, + "help": "Sets the linker mode for npm packages (isolated or hoisted)", + "help_heading": "Dependency management options", + "usage": "--node-modules-linker=" + }, { "name": "vendor", "short": null, @@ -8005,6 +8999,15 @@ "help_heading": null, "usage": "--yes" }, + { + "name": "package", + "short": "p", + "long": "package", + "required": false, + "help": "Package to install (use when the binary name differs from the package name)", + "help_heading": null, + "usage": "--package " + }, { "name": "check", "short": null, @@ -8204,6 +9207,13 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help install\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "ci", + "about": null, + "args": [], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help ci\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, { "name": "json_reference", "about": null, @@ -8260,6 +9270,13 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help publish\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "pack", + "about": null, + "args": [], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help pack\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, { "name": "repl", "about": null, @@ -8281,6 +9298,13 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help test\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "transpile", + "about": null, + "args": [], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help transpile\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, { "name": "types", "about": null, @@ -8302,6 +9326,13 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help upgrade\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "bump-version", + "about": null, + "args": [], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help bump-version\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, { "name": "vendor", "about": null, @@ -8309,6 +9340,13 @@ "subcommands": [], "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help vendor\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" }, + { + "name": "why", + "about": null, + "args": [], + "subcommands": [], + "usage": "\u001b[37mUsage:\u001b[0m \u001b[32mdeno help why\u001b[0m \u001b[32m[OPTIONS]\u001b[0m" + }, { "name": "x", "about": null, diff --git a/runtime/reference/cli/add.md b/runtime/reference/cli/add.md index 28a606e7d..37fd79ea8 100644 --- a/runtime/reference/cli/add.md +++ b/runtime/reference/cli/add.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-12 +last_modified: 2026-05-20 title: "deno add" command: add openGraphLayout: "/open_graph/cli-commands.jsx" @@ -18,9 +18,19 @@ For more on how Deno handles dependencies, see Add packages from JSR and npm: ```sh -deno add @std/path npm:express +deno add npm:express hono zod +deno add jsr:@std/path ``` +:::info Deno 2.8 + +Unprefixed package names are treated as npm packages by default, so the `npm:` +prefix is no longer required at the CLI. `deno add express` is equivalent to +`deno add npm:express`. JSR packages still need the `jsr:` prefix to stay +unambiguous. The `npm:` prefix remains required in `import` specifiers. + +::: + By default, dependencies are added with a caret (`^`) version range. Use `--save-exact` to pin to an exact version: @@ -31,14 +41,21 @@ deno add --save-exact @std/path This saves the dependency without the `^` prefix (e.g., `1.0.0` instead of `^1.0.0`). -Treat unprefixed package names as npm packages: - -```sh -deno add --npm express -``` - ## Where dependencies are stored If your project has a `package.json`, npm packages will be added to `dependencies` in `package.json`. Otherwise, all packages are added to the `imports` field in [`deno.json`](/runtime/fundamentals/configuration/). + +To force every dependency to be written to `package.json` (creating one if +needed), pass `--package-json` (Deno 2.8+): + +```sh +deno add --package-json npm:express jsr:@std/path +``` + +JSR packages added with `--package-json` are written in their npm-compatible +form (`npm:@jsr/...`). The same flag works on +[`deno install`](/runtime/reference/cli/install/), +[`deno remove`](/runtime/reference/cli/remove/), and +[`deno uninstall`](/runtime/reference/cli/uninstall/). diff --git a/runtime/reference/cli/audit.md b/runtime/reference/cli/audit.md index 5901b7ac2..5a71ee015 100644 --- a/runtime/reference/cli/audit.md +++ b/runtime/reference/cli/audit.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-12 +last_modified: 2026-05-20 title: "deno audit" command: audit openGraphLayout: "/open_graph/cli-commands.jsx" @@ -48,3 +48,41 @@ Don't error if the audit data can't be retrieved from the registry: ```sh deno audit --ignore-registry-errors ``` + +## Auto-fixing vulnerabilities + +Starting in Deno 2.8, pass `--fix` to automatically upgrade vulnerable direct +dependencies to a patched, semver-compatible version: + +```sh +deno audit --fix +``` + +`deno audit --fix` updates `package.json` / `deno.json` and regenerates the +lockfile. To keep changes safe, it deliberately **skips**: + +- Major-version upgrades (reported as unfixable so you can bump them + intentionally). +- Unsupported version specifier styles such as `>=1 <2`, `1.x`, dist-tags, or + aliases — rather than silently rewriting them to a caret range. +- Transitive dependencies that don't have a clean direct-dependency upgrade + path. These are surfaced as "could not be fixed automatically". + +Example output: + +``` +╭ @denotest/with-vuln1 is susceptible to prototype pollution +│ ... +Found 2 vulnerabilities +Severity: 0 low, 0 moderate, 1 high, 1 critical + +Fixed 1 vulnerability: + @denotest/with-vuln1 1.0.0 -> 1.1.0 + +1 vulnerability could not be fixed automatically: + @denotest/with-vuln2 (major upgrade to 2.0.0) +``` + +For a typical CI workflow, run `deno audit` after +[`deno ci`](/runtime/reference/cli/ci/) so the install and the security check +share the same reproducible state. diff --git a/runtime/reference/cli/bump_version.md b/runtime/reference/cli/bump_version.md new file mode 100644 index 000000000..1ef7d6581 --- /dev/null +++ b/runtime/reference/cli/bump_version.md @@ -0,0 +1,157 @@ +--- +last_modified: 2026-04-29 +title: "deno bump-version" +command: bump-version +openGraphLayout: "/open_graph/cli-commands.jsx" +openGraphTitle: "deno bump-version" +description: "Bump the project version field in deno.json or package.json" +--- + +The `deno bump-version` command updates the `version` field in your project's +configuration file, similar to `npm version`. It reads and writes the `version` +field in `deno.json(c)` if present, otherwise it falls back to `package.json`. + +:::caution + +`deno bump-version` is experimental and subject to change. + +::: + +## Usage + +```sh +deno bump-version [increment] +``` + +The `increment` argument selects how the version is bumped: + +| Increment | Example | +| ------------ | --------------------- | +| `patch` | `1.4.6` → `1.4.7` | +| `minor` | `1.4.6` → `1.5.0` | +| `major` | `1.4.6` → `2.0.0` | +| `prepatch` | `1.4.6` → `1.4.7-0` | +| `preminor` | `1.4.6` → `1.5.0-0` | +| `premajor` | `1.4.6` → `2.0.0-0` | +| `prerelease` | `1.4.7-0` → `1.4.7-1` | + +If `increment` is omitted, the current version is printed and the configuration +file is left unchanged. + +If the configuration file has no `version` field and an increment is given, the +version defaults to `0.1.0`. + +The command exits with an error if neither `deno.json` nor `package.json` is +found in the current directory. + +## Examples + +Release a patch: + +```sh +deno bump-version patch +``` + +Cut a new minor release: + +```sh +deno bump-version minor +``` + +Iterate on a prerelease: + +```sh +deno bump-version prerelease +``` + +Print the current version without modifying the file: + +```sh +deno bump-version +``` + +After bumping, commit the updated configuration file as part of your release. +For publishing the bumped version to JSR, see +[`deno publish`](/runtime/reference/cli/publish/); for an npm tarball, see +[`deno pack`](/runtime/reference/cli/pack/). + +## Workspace mode + +When run at the root of a [workspace](/runtime/fundamentals/workspaces/), +`deno bump-version` operates on every member package in a single pass instead of +just the root config: + +- The same increment is applied to each member's `version` field. +- `jsr:` version constraints in the workspace root config and in any + [import map](/runtime/fundamentals/configuration/#imports) are rewritten in + place so cross-package references keep matching the bumped versions. +- Members without a `version` field are left alone. + +```sh +# At the workspace root: patch every member from 1.4.6 to 1.4.7 +deno bump-version patch +``` + +This avoids the manual coordination step where a workspace release used to +require updating each member's `deno.json`/`package.json` and the root import +map one at a time. + +## Deriving bumps from Conventional Commits + +Inside a workspace, running `deno bump-version` with no `increment` argument +switches to deriving per-package bumps from +[Conventional Commits](https://www.conventionalcommits.org/) between a base ref +and the current branch. Each member's bump is computed independently from the +commits that touched files inside it (honoring scoped commits and wildcard `*` +scopes), and the bumped versions are written back to the member configs and any +import-map constraints. + +The derivation rules: + +- `fix:` and other patch-level types → `patch`. +- `feat:` → `minor`. +- A commit marked `BREAKING CHANGE:` in the body or with a `!` after the type + (e.g. `feat!:`) → `major`. +- For packages still on `0.x.y`, semver rules are applied conservatively: a + breaking change yields a `minor` bump rather than `major`, and a `feat:` + yields `patch`. +- Prereleases (`-0`, `-1`, …) get a `prerelease` increment. +- Any manual edits to a package's version since the base ref are treated as + authoritative and skipped — the tool won't overwrite a deliberate version + pick. + +```sh +# Derive the bumps from commits between `main` and the current branch +deno bump-version --base=main +``` + +### Selecting the range + +Two flags pin the comparison range when the default (the current branch since +the latest tag) isn't what you want: + +- `--base=` — the ref to compare against. Usually a release branch or tag + (`--base=main`, `--base=v1.4.7`). +- `--start=` — the ref where the changeset begins. Defaults to the merge + base between `--base` and `HEAD`. + +```sh +# Bump based on commits between v1.4.7 and the current branch +deno bump-version --base=v1.4.7 + +# Bump based on commits between two explicit refs +deno bump-version --base=v1.4.7 --start=release/1.5 +``` + +### `--dry-run` + +Pass `--dry-run` to print the planned changes — which packages would bump, the +old/new version pairs, and the rewritten `jsr:` constraints — without writing +anything to disk: + +```sh +deno bump-version --base=main --dry-run +``` + +This is a good fit for CI checks ("does this branch produce the bumps we +expect?") and for previewing a release locally before committing. diff --git a/runtime/reference/cli/ci.md b/runtime/reference/cli/ci.md new file mode 100644 index 000000000..869168406 --- /dev/null +++ b/runtime/reference/cli/ci.md @@ -0,0 +1,126 @@ +--- +last_modified: 2026-05-20 +title: "deno ci" +command: ci +openGraphLayout: "/open_graph/cli-commands.jsx" +openGraphTitle: "deno ci" +description: "Reproducible install for CI environments" +--- + +`deno ci` performs a reproducible install for CI environments, mirroring +`npm ci`. Use it in CI scripts and Dockerfiles when you want a single, greppable +command that's guaranteed to install exactly what the lockfile records — no +drift, no leftover state, no surprises. + +```sh +deno ci +``` + +## What it does + +`deno ci` is roughly equivalent to: + +```sh +rm -rf node_modules +deno install --frozen +``` + +but with stricter error handling and clearer failure modes: + +1. **Requires a lockfile.** If `deno.lock` is missing or unreadable, `deno ci` + errors out instead of generating one. This guarantees that two runs of the + same commit install the same versions. +2. **Wipes `node_modules` first.** Any stale state from a previous CI step (or a + leaked development install) is removed before installing, so the final tree + reflects only what the lockfile resolved to. +3. **Locks resolution with `--frozen`.** If `deno.json` or `package.json` has + been edited without re-running `deno install` to refresh the lockfile, the + command fails. This catches "I bumped a version but forgot to commit the + lockfile" mistakes before they reach production. + +If any of those checks fail, the install does not proceed. + +## When to use it + +| Scenario | Use | +| -------------------------------------- | -------------------------- | +| CI build / test / lint pipeline | `deno ci` | +| Production Docker image | `deno ci --prod` | +| Local development (frequent edits) | `deno install` | +| Adding or removing a package | `deno add` / `deno remove` | +| First-time bootstrap (no lockfile yet) | `deno install` | + +The rule of thumb: pick `deno ci` whenever the install must be reproducible and +there is no expectation that the lockfile should change. Pick `deno install` +whenever you're iterating on dependencies. + +## Examples + +### GitHub Actions + +```yaml title=".github/workflows/test.yml" +name: Test + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + - run: deno ci + - run: deno test + - run: deno lint + - run: deno fmt --check +``` + +### Production Dockerfile + +```dockerfile +FROM denoland/deno:2.8.0 +WORKDIR /app + +# Copy the manifest files first so install caches well +COPY deno.json deno.lock package.json* ./ +RUN deno ci --prod + +# Then copy the rest of the source +COPY . . +CMD ["deno", "run", "-A", "main.ts"] +``` + +Splitting the `COPY` into "manifests first, source after" lets Docker reuse the +`deno ci` layer whenever your dependencies are unchanged. + +### Production install on the host + +```sh +deno ci --prod --skip-types +``` + +`--prod` skips `devDependencies` from `package.json`. `--skip-types` drops +`@types/*` packages from both `deno.json` imports and `package.json` +dependencies — useful in deployment artifacts where types add weight and aren't +needed at runtime. + +## Common failure modes + +| Error | Likely cause | Fix | +| ------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| "deno.lock is missing" | No lockfile is committed. | Run `deno install` locally and commit the resulting `deno.lock`. | +| "lockfile is out of date" | A dependency was added or bumped in `deno.json` / `package.json` but the lockfile wasn't refreshed. | Run `deno install` locally and commit the updated `deno.lock`. | +| Build-script approval prompts in non-TTY CI | A new npm package wants to run lifecycle scripts that haven't been approved. | Approve them locally with [`deno approve-scripts`](/runtime/reference/cli/approve_scripts/) and commit the approvals. | + +## See also + +- [`deno install`](/runtime/reference/cli/install/) — everyday install, with + full flag reference +- [Continuous integration](/runtime/reference/continuous_integration/) — guide + to running Deno in GitHub Actions and other CI providers +- [`deno audit`](/runtime/reference/cli/audit/) — scan dependencies for known + vulnerabilities, complements `deno ci` in CI +- [`deno approve-scripts`](/runtime/reference/cli/approve_scripts/) — manage + which npm lifecycle scripts are allowed to run diff --git a/runtime/reference/cli/compile.md b/runtime/reference/cli/compile.md index 4a164615d..d60cb182e 100644 --- a/runtime/reference/cli/compile.md +++ b/runtime/reference/cli/compile.md @@ -30,6 +30,40 @@ deno compile --allow-read --allow-net jsr:@std/http/file-server -p 8080 ./file_server --help ``` +## Framework detection + +Starting in Deno 2.8, `deno compile .` (or `deno compile `) detects +common web frameworks and produces an entrypoint that knows how to start them. +The detected build script is run first, so the compiled binary always contains a +fresh build. + +Supported frameworks: + +- Next.js +- Astro +- Fresh (1.x and 2.x) +- Remix +- SvelteKit +- Nuxt +- SolidStart +- TanStack Start +- Vite (SSR mode) + +```sh +# In a Next.js / Astro / Fresh / etc. project +deno compile . + +# Or pointing at a specific app directory +deno compile ./apps/web +``` + +Generated entrypoints use `import.meta.dirname` so framework asset paths resolve +correctly against the [virtual filesystem](#including-data-files-or-directories) +inside the compiled binary. + +If the project doesn't match any supported framework, `deno compile` will error +out. + ## Cross Compilation You can cross-compile binaries for other platforms by using the `--target` flag. @@ -114,6 +148,26 @@ const dataFiles = Deno.readDirSync(import.meta.dirname + "/data"); Note this currently only works for files on the file system and not remote files. +### Configuring `include` / `exclude` in `deno.json` + +The `--include` and `--exclude` paths can be set declaratively in `deno.json` so +you don't have to repeat them on every `deno compile` invocation: + +```jsonc title="deno.json" +{ + "compile": { + "include": ["names.csv", "data", "worker.ts"], + "exclude": ["data/secrets", "**/*.test.ts"] + } +} +``` + +CLI flags are merged with the config: `--include` and `--exclude` add to the +lists in `deno.json` rather than replacing them. See the +[Compile config](/runtime/fundamentals/configuration/#compile-config) section in +the configuration guide for more details, including how to declare `permissions` +on the same block. + ## Workers Similarly to non-statically analyzable dynamic imports, code for diff --git a/runtime/reference/cli/coverage.md b/runtime/reference/cli/coverage.md index ad35c266b..cb1d76ba7 100644 --- a/runtime/reference/cli/coverage.md +++ b/runtime/reference/cli/coverage.md @@ -1,5 +1,5 @@ --- -last_modified: 2025-04-23 +last_modified: 2026-05-20 title: "deno coverage" oldUrl: /runtime/manual/tools/coverage/ command: coverage @@ -128,6 +128,26 @@ console.log("This line is ignored"); console.log("This line is not ignored"); ``` +## Function coverage + +The summary table and the HTML report include a **function coverage** column +alongside the branch and line columns: + +```console +--------------------------------------------- +File | Branch % | Line % | Function % +--------------------------------------------- +main.ts | 85.7 | 92.3 | 100.0 +util.ts | 75.0 | 88.5 | 66.7 +--------------------------------------------- +all files | 80.0 | 90.5 | 83.3 +--------------------------------------------- +``` + +Function coverage measures the percentage of declared functions that were called +at least once during the test run. The same data is also available in the `lcov` +output. + ## Output Formats By default we support Deno's own coverage format - but you can also output diff --git a/runtime/reference/cli/doc.md b/runtime/reference/cli/doc.md index 6aa3d86b1..d9bec3211 100644 --- a/runtime/reference/cli/doc.md +++ b/runtime/reference/cli/doc.md @@ -38,6 +38,22 @@ function add(x: number, y: number): number Adds x and y. @param {number} x @param {number} y @returns {number} Sum of x and y ``` +### Documenting an npm or JSR package + +Starting in Deno 2.8, `deno doc` accepts `npm:` and `jsr:` specifiers and will +fetch the package's published types before generating documentation. This is +useful for exploring a third-party API from the terminal without cloning the +repository: + +```sh +deno doc npm:code-block-writer +deno doc jsr:@std/path +``` + +You can pin to a specific version like any other Deno specifier (`npm:zod@4`), +and combine the specifier with `--html` or `--json` to render the same output +formats as for local files. + ## Linting You can use `--lint` flag to check for problems in your documentation while it's diff --git a/runtime/reference/cli/env_variables.md b/runtime/reference/cli/env_variables.md index e76cbbf4b..ad54bb3a9 100644 --- a/runtime/reference/cli/env_variables.md +++ b/runtime/reference/cli/env_variables.md @@ -1,10 +1,18 @@ --- -last_modified: 2024-10-07 +last_modified: 2026-05-20 title: "Configuring Deno behavior" --- There are several environment variables which can impact the behavior of Deno: +### DENO_AUDIT_PERMISSIONS + +Audit every permission access (allowed or denied). Set to a file path to write a +JSONL audit log, or to the literal value `otel` to emit each access as an +OpenTelemetry log record via the configured exporter. See +[permissions](/runtime/fundamentals/security/#permission-flags) for the field +set and the OTel attribute names. + ### DENO_AUTH_TOKENS A list of authorization tokens which can be used to allow Deno to access remote @@ -86,6 +94,14 @@ permission to read the environment variables by checking the value of Indicates hosts which should bypass the proxy set in the other environment variables. See the [Proxies](#proxies) section for more information. +### NODE_EXTRA_CA_CERTS + +Path to a PEM file with extra certificate authorities. Loaded at the root +certificate store level, so the certs are honored by `fetch()`, +[`Deno.connectTls()`](/api/deno/~/Deno.connectTls), and the Node compat APIs +(`node:https`, `node:tls`). Available in Deno 2.8+. Missing or invalid files +emit a warning rather than failing, matching Node.js semantics. + ### NPM_CONFIG_REGISTRY The npm registry to use when loading modules via diff --git a/runtime/reference/cli/eval.md b/runtime/reference/cli/eval.md index 8fc21a087..c5170ac4a 100644 --- a/runtime/reference/cli/eval.md +++ b/runtime/reference/cli/eval.md @@ -1,5 +1,5 @@ --- -last_modified: 2025-03-10 +last_modified: 2026-05-20 title: "deno eval" oldUrl: /runtime/manual/tools/eval/ command: eval @@ -24,14 +24,30 @@ TypeScript works out of the box: deno eval "const greeting: string = 'Hello'; console.log(greeting)" ``` -## CommonJS support +## CommonJS and ESM auto-detection -CommonJS modules are automatically recognized and supported: +Starting in Deno 2.8, `deno eval` defaults to ESM but switches to CommonJS when +the snippet looks like a CJS script. A snippet is treated as CJS only when it +has no `import` / `export` declarations **and** it references one of the +CommonJS-specific bindings: `require(`, `module.exports`, `exports.`, +`__dirname`, or `__filename`. Anything else — including plain expressions — runs +as ESM, matching the longstanding `deno eval` default. ```sh +# Detected as CommonJS — uses require() deno eval "const path = require('path'); console.log(path.join('a', 'b'))" + +# Runs as ESM (the default) — no CJS-specific patterns +deno eval "console.log(1 + 2)" + +# Runs as ESM because of the static import +deno eval "import { ok } from 'node:assert'; ok(true); console.log('ok')" ``` +If the heuristic gets it wrong — for example when a snippet mentions `require` +only inside a string — pass `--ext=mjs` to force ESM or `--ext=cjs` to force +CommonJS. + ## Printing expression results Use `--print` (or `-p`) to evaluate an expression and print its result, similar diff --git a/runtime/reference/cli/index.md b/runtime/reference/cli/index.md index e910755dc..70c68baff 100644 --- a/runtime/reference/cli/index.md +++ b/runtime/reference/cli/index.md @@ -25,6 +25,8 @@ below for more information on each subcommand. - [deno approve-scripts](/runtime/reference/cli/approve_scripts) - manage lifecycle scripts of npm packages - [deno audit](/runtime/reference/cli/audit) - audit dependencies +- [deno bump-version](/runtime/reference/cli/bump_version/) - bump the project + version in `deno.json` or `package.json` - deno cache - _(Deprecated. Please use [deno install](/runtime/reference/cli/install/))_ - [deno install](/runtime/reference/cli/install/) - install a dependency or a @@ -34,6 +36,8 @@ below for more information on each subcommand. - [deno remove](/runtime/reference/cli/remove) - Remove dependencies - [deno outdated](/runtime/reference/cli/outdated) - view or update outdated dependencies +- [deno why](/runtime/reference/cli/why/) - explain why a package is in the + dependency tree ## Tooling @@ -58,8 +62,12 @@ below for more information on each subcommand. - [deno jupyter](/runtime/reference/cli/jupyter/) - run a Jupyter notebook - [deno lint](/runtime/reference/cli/lint/) - lint your code - [deno lsp](/runtime/reference/cli/lsp/) - language server protocol integration +- [deno pack](/runtime/reference/cli/pack/) - create an npm tarball from the + current Deno project - [deno publish](/runtime/reference/cli/publish/) - publish a module to JSR - [deno test](/runtime/reference/cli/test/) - run your tests +- [deno transpile](/runtime/reference/cli/transpile/) - transpile TypeScript, + JSX, or TSX to JavaScript - [deno types](/runtime/reference/cli/types/) - print runtime types - [deno upgrade](/runtime/reference/cli/upgrade/) - upgrade Deno to the latest version diff --git a/runtime/reference/cli/install.md b/runtime/reference/cli/install.md index 517e68792..e55c6148d 100644 --- a/runtime/reference/cli/install.md +++ b/runtime/reference/cli/install.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-12 +last_modified: 2026-05-20 title: "deno install" oldUrl: - /runtime/manual/tools/script_installer/ @@ -36,6 +36,15 @@ Use this command to install particular packages and add them to `deno.json` or deno install jsr:@std/testing npm:express ``` +:::info Deno 2.8 + +Unprefixed package names are treated as npm packages by default, so the `npm:` +prefix is no longer required at the CLI. `deno install express` is equivalent to +`deno install npm:express`. JSR packages still need the `jsr:` prefix to stay +unambiguous. The `npm:` prefix remains required in `import` specifiers. + +::: + :::tip You can also use `deno add` which is an alias to `deno install [PACKAGES]` @@ -46,6 +55,46 @@ If your project has a `package.json` file, the packages coming from npm will be added to `dependencies` in `package.json`. Otherwise all packages will be added to `deno.json`. +### deno install --os and --arch + +Starting in Deno 2.8, `deno install` accepts `--os` and `--arch` flags so you +can install npm packages targeting a different platform than the one you're +running on. This is most useful for pre-installing packages with native binaries +— for example, building a deployment artifact on a macOS dev machine that will +eventually run on Linux/arm64. + +The flags accept Node.js-compatible values, the same strings that +`process.platform` and `process.arch` produce. + +```sh +# Install npm packages for linux/arm64 +deno install --os linux --arch arm64 + +# Install for windows/x64 +deno install --os win32 --arch x64 + +# Override just the architecture; --os defaults to the current system +deno install --arch x64 +``` + +`--os` and `--arch` are local-install-only and conflict with `--global`. + +### deno install --package-json + +By default, Deno picks the configuration file to write to (`deno.json` or +`package.json`) based on which one is closest to the current working directory. +Starting in Deno 2.8, `--package-json` forces dependencies to be written to +`package.json`, regardless of any nearby `deno.json`. If no `package.json` +exists yet, one is created. + +```sh +deno install --package-json npm:express jsr:@std/path +``` + +JSR packages added with `--package-json` are written in their npm-compatible +form (`npm:@jsr/...`). The same flag works on `deno add`, `deno remove`, and +`deno uninstall`. + ### deno install --entrypoint [FILES] Use this command to install all dependencies that are used in the provided files @@ -177,6 +226,54 @@ This combines the behavior of [`deno compile`](/runtime/reference/cli/compile/) with global installation — producing a native binary placed in the installation root (same as `--global` without `--compile`). +### deno install --prod + +Use this command to install only production dependencies, skipping +`devDependencies` from `package.json`. + +```sh +deno install --prod +``` + +This is useful when deploying an application where development dependencies like +test frameworks or build tools are not needed. + +The `--prod` flag conflicts with `--global` and `--dev`. + +In CI environments, prefer [`deno ci --prod`](/runtime/reference/cli/ci/), which +also enforces a frozen lockfile and removes any pre-existing `node_modules` +before installing. + +#### --skip-types + +When combined with `--prod`, the `--skip-types` flag additionally skips +`@types/*` packages from both `package.json` dependencies and `deno.json` +imports: + +```sh +deno install --prod --skip-types +``` + +:::caution + +The `--skip-types` flag identifies type packages by checking if the package name +starts with `@types/`. This heuristic may not cover all type-only packages. + +::: + +#### --prod with --entrypoint + +When `--prod` is combined with `--entrypoint`, the module graph is built as +"code only", which excludes type-only dependencies: + +```sh +deno install --prod --entrypoint main.ts +``` + +This provides the most precise production install — only dependencies that are +actually imported at runtime by the specified entrypoint (and its transitive +imports) will be installed. + ## Native Node.js addons A lot of popular packages npm packages like diff --git a/runtime/reference/cli/pack.md b/runtime/reference/cli/pack.md new file mode 100644 index 000000000..5762edb0e --- /dev/null +++ b/runtime/reference/cli/pack.md @@ -0,0 +1,233 @@ +--- +last_modified: 2026-05-20 +title: "deno pack" +command: pack +openGraphLayout: "/open_graph/cli-commands.jsx" +openGraphTitle: "deno pack" +description: "Create an npm tarball from a Deno project for publishing to npm" +--- + +The `deno pack` command builds an npm-compatible tarball (`.tgz`) from a Deno +project, so you can publish a Deno-authored library straight to the npm +registry. It transpiles TypeScript to JavaScript, generates `.d.ts` declaration +files, rewrites import specifiers, and synthesizes a `package.json` that +npm-only consumers can understand. + +`deno pack` is **not** equivalent to `npm pack`. It's a build step that converts +a Deno/JSR project into an npm-publishable package — closer to +[`deno transpile`](/runtime/reference/cli/transpile/) plus `npm pack` combined. +It does not read an existing `package.json`, does not honor `.npmignore`, and +does not run `prepublishOnly` / `prepare` lifecycle scripts. + +## Quick start + +```sh +deno pack +``` + +`deno pack` reads the package metadata from `deno.json` (the `name`, `version`, +and `exports` you'd use to publish to JSR) and writes a gzipped tarball to the +current directory. + +Given a `deno.json` like: + +```json title="deno.json" +{ + "name": "@scope/my-lib", + "version": "1.0.0", + "exports": "./mod.ts" +} +``` + +`deno pack` produces `scope-my-lib-1.0.0.tgz` (the `@` is stripped and `/` +becomes `-`, matching `npm pack`'s naming convention). + +## What's in the tarball + +| Contents | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| A generated `package.json` with `name`, `version`, `type: "module"`, conditional `exports` (`types` / `import` / `default`), and a `dependencies` field derived from your `jsr:` / `npm:` imports. | +| Transpiled `.js` files (with inline source maps by default; pass `--no-source-maps` to omit). | +| Generated `.d.ts` declaration files (produced via the same fast-check pipeline as [`deno publish`](/runtime/reference/cli/publish/)). | +| `README` and `LICENSE` files from the project root, if present. | + +Only files reachable through the module graph from `exports` are included. +Non-JS assets such as data files or WASM are only included if they're imported +from JS/TS. If you need to ship arbitrary files, list them as positional +arguments: + +```sh +deno pack assets/icon.svg locales/*.json +``` + +## Specifier rewriting + +For the generated package to work on Node and other npm consumers, `deno pack` +rewrites imports as it transpiles: + +| In your source | In the tarball | Notes | +| --------------- | ---------------- | ---------------------------------------------------- | +| `jsr:@std/path` | `@jsr/std__path` | Consumers need the JSR npm registry configured. | +| `npm:express@4` | `express` | Version moves into `dependencies` in `package.json`. | +| `./utils.ts` | `./utils.js` | Extension only — no path restructuring. | +| `node:fs` | `node:fs` | Unchanged. | + +Because JSR imports turn into `@jsr/...` specifiers, anyone installing the +published tarball needs the JSR npm registry configured. The simplest way is to +run [`npx jsr add`](https://jsr.io/docs/npm-compatibility) once in the consumer +project; that sets up the `.npmrc` entries for the `@jsr` scope. + +## Deno API shimming + +If your code uses the `Deno.*` global, `deno pack` adds +[`@deno/shim-deno`](https://www.npmjs.com/package/@deno/shim-deno) as a runtime +dependency and injects the shim so the package can run under Node.js. The shim +covers the subset of `Deno.*` that maps cleanly onto Node APIs — review the +shim's docs to see what's polyfilled. + +Pass `--no-deno-shim` to opt out, e.g. if you've already provided your own +abstraction or only intend the package to run under Deno-on-npm. + +## Publishing to npm + +```sh +deno pack +npm publish ./scope-my-lib-1.0.0.tgz +``` + +A typical release flow: + +```sh +# 1. Bump the version +deno bump-version patch + +# 2. Build the tarball +deno pack + +# 3. Verify the contents (extracted view) +tar -tzf scope-my-lib-1.0.0.tgz + +# 4. Push to npm +npm publish ./scope-my-lib-1.0.0.tgz +``` + +For JSR releases, use [`deno publish`](/runtime/reference/cli/publish/) instead +— `deno pack` is specifically for the npm registry. + +## Workspace support + +In a [workspace](/runtime/fundamentals/workspaces/), `deno pack` runs against +the current working directory's member. To pack a specific member from the root: + +```sh +cd packages/my-lib +deno pack +``` + +Cross-workspace `npm:` / `jsr:` dependencies are rewritten in the generated +`package.json` to point at their published versions, not to other workspace +members — make sure those dependencies have been released independently before +publishing your tarball. + +## Examples + +### Override the version + +Useful when releasing a one-off prerelease without editing `deno.json`: + +```sh +deno pack --set-version 2.0.0-rc.1 +``` + +### Pick the output path + +```sh +deno pack --output dist/my-package.tgz +``` + +### Preview without writing + +```sh +deno pack --dry-run +``` + +`--dry-run` prints what _would_ be in the tarball without producing one — handy +in CI to verify file inclusion rules. + +### Allow slow types + +[Slow types](https://jsr.io/docs/about-slow-types) prevent `.d.ts` generation. +Pass `--allow-slow-types` to pack anyway; the tarball will not include +declaration files. + +```sh +deno pack --allow-slow-types +``` + +### Skip the Deno shim + +```sh +deno pack --no-deno-shim +``` + +### Pack despite a dirty working tree + +```sh +deno pack --allow-dirty +``` + +By default `deno pack` refuses to pack when the git working tree has uncommitted +changes, to make releases reproducible from the commit hash. + +### Exclude files + +```sh +deno pack --ignore=tests/ --ignore='**/*.test.ts' +``` + +`--ignore` accepts glob patterns. Combine multiple `--ignore` flags to add +patterns. + +### Omit source maps + +```sh +deno pack --no-source-maps +``` + +By default, source maps are inlined in the emitted `.js` files. Use +`--no-source-maps` to strip them — smaller tarballs, but harder to debug +upstream. + +## Limitations + +- **No `bin` entries.** `deno pack` does not synthesize the `package.json` `bin` + field. Library publishing is supported; CLI tools that need a `node`-shebanged + executable still need a hand-rolled npm package. +- **No native addons.** Packages that link against native code or ship a + `node-gyp` build step are out of scope. +- **No `.npmignore`.** Use `--ignore` for excludes; `.gitignore` is honored for + what's considered part of the project. +- **No lifecycle scripts.** `prepublishOnly` / `prepare` / `postinstall` hooks + from a hand-written `package.json` are not run because the `package.json` is + generated, not read. + +## When to use `deno pack` vs `deno publish` + +| Need | Use | +| --------------------------------------------------- | ------------------------------------------------- | +| Release to [JSR](https://jsr.io) | [`deno publish`](/runtime/reference/cli/publish/) | +| Release the same library to npm | `deno pack` → `npm publish ./*.tgz` | +| Reach Node-only consumers without forcing JSR setup | `deno pack` (rewrites JSR imports for them) | + +A library can ship to both — release to JSR with `deno publish`, then build and +push a tarball to npm with `deno pack` for users who haven't adopted JSR yet. + +## See also + +- [`deno publish`](/runtime/reference/cli/publish/) — release to JSR +- [`deno transpile`](/runtime/reference/cli/transpile/) — the emit step that + `deno pack` uses internally +- [`deno bump-version`](/runtime/reference/cli/bump_version/) — bump `version` + in `deno.json` / `package.json` before packing +- [Publishing modules](/runtime/fundamentals/modules/#publishing-modules) — + overview of where Deno-authored libraries can be published diff --git a/runtime/reference/cli/publish.md b/runtime/reference/cli/publish.md index 93c85b294..827f74caf 100644 --- a/runtime/reference/cli/publish.md +++ b/runtime/reference/cli/publish.md @@ -17,7 +17,8 @@ Your package must have a `name` and `version` and an `exports` field in its - The `name` field must be unique and follow the `@/` convention. -- The `version` field must be a valid semver version. +- The `version` field must be a valid semver version. To bump it as part of your + release flow, see [`deno bump-version`](/runtime/reference/cli/bump_version/). - The `exports` field must point to the main entry point of the package. The exports field can either be specified as a single string, or as an object mapping entrypoint names to paths in your package. diff --git a/runtime/reference/cli/run.md b/runtime/reference/cli/run.md index ef2de2486..8b278e66e 100644 --- a/runtime/reference/cli/run.md +++ b/runtime/reference/cli/run.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-12 +last_modified: 2026-05-20 title: "deno run" oldUrl: /runtime/manual/tools/run/ command: run @@ -67,6 +67,20 @@ deno run --allow-net --watch server.ts Deno's watcher will notify you of changes in the console, and will warn in the console if there are errors while you work. +The same `--watch` flag is also accepted by +[`deno test`](/runtime/reference/cli/test/), +[`deno serve`](/runtime/reference/cli/serve/), and +[`deno bench`](/runtime/reference/cli/bench/). + +:::info Deno 2.8 + +When the watcher restarts the process, Deno sends `SIGTERM` first so `unload` +event listeners and `process.exit` hooks run, then waits 500ms before the hard +kill. This gives graceful-shutdown code time to flush resources between +restarts. + +::: + ## Running a package.json script `package.json` scripts can be executed with the diff --git a/runtime/reference/cli/task.md b/runtime/reference/cli/task.md index 214e61327..c7cbf372b 100644 --- a/runtime/reference/cli/task.md +++ b/runtime/reference/cli/task.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-12 +last_modified: 2026-05-20 title: "deno task" oldUrl: - /runtime/tools/task_runner/ @@ -146,6 +146,15 @@ Dependency tasks are executed in parallel, with the default parallel limit being equal to number of cores on your machine. To change this limit, use the `DENO_JOBS` environmental variable. +:::info Deno 2.8 + +When tasks run in parallel, each output line is prefixed with the task name that +produced it (color-coded per task). Prefixes stay attached even when a task +forks subprocesses, so a parallel `build` + `test` + `lint` run stays legible +without an external multiplexer. + +::: + Dependencies are tracked and if multiple tasks depend on the same task, that task will only be run once: @@ -586,6 +595,10 @@ enabled. - **pipefail** - When enabled, the exit code of a pipeline is the exit code of the last command to exit with a non-zero status, or zero if all commands exit successfully. Enable with `set -o pipefail`. +- **errexit** (Deno 2.8+) - When enabled, a sequential list aborts on the first + command that exits non-zero. Enable with `set -e` or `set -o errexit`; disable + again with `set +e` or `set +o errexit`. Useful when porting a shell script + that relies on `set -e` semantics into a `tasks` block. Examples: @@ -599,7 +612,9 @@ Examples: // disable globstar "task3": "shopt -u globstar && echo **/*.ts", // enable pipefail - "task4": "set -o pipefail && cat missing.txt | echo 'hello'" + "task4": "set -o pipefail && cat missing.txt | echo 'hello'", + // abort the sequential list on the first failing command + "task5": "set -e; build_step_one; build_step_two; build_step_three" } } ``` @@ -645,6 +660,10 @@ box on Windows, Mac, and Linux. environment variables. - [`xargs`](https://man7.org/linux/man-pages/man1/xargs.1p.html) - Builds arguments from stdin and executes a command. +- [`:`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/colon.html) - + The POSIX null command. Does nothing and always exits with status `0` (Deno + 2.8+). Handy as a no-op placeholder in conditionals or for parameter-expansion + side effects. If you find a useful flag missing on a command or have any suggestions for additional commands that should be supported out of the box, then please diff --git a/runtime/reference/cli/transpile.md b/runtime/reference/cli/transpile.md new file mode 100644 index 000000000..3fd1c2c97 --- /dev/null +++ b/runtime/reference/cli/transpile.md @@ -0,0 +1,139 @@ +--- +last_modified: 2026-05-20 +title: "deno transpile" +command: transpile +openGraphLayout: "/open_graph/cli-commands.jsx" +openGraphTitle: "deno transpile" +description: "Transpile TypeScript, JSX, or TSX to JavaScript" +--- + +The `deno transpile` command emits JavaScript from TypeScript, JSX, or TSX +sources. It's useful when you need plain `.js` output to ship to a runtime that +doesn't understand TypeScript, or to feed into a build step that expects +JavaScript. + +For most workflows you do **not** need `deno transpile` — `deno run`, +`deno test`, and `deno serve` already accept `.ts` / `.tsx` files directly. +Reach for it when: + +- You're shipping a library to consumers that run `node` or a browser bundler + directly. (For npm tarballs, prefer + [`deno pack`](/runtime/reference/cli/pack/), which wraps `deno transpile` with + packaging logic.) +- A downstream tool only understands `.js`. +- You want pre-compiled `.js` checked into a build artifact rather than + transpiled on the fly. + +## Usage + +```sh +deno transpile [flags] +``` + +`` is one or more source file paths (globs are expanded by the shell). +`deno transpile` does **not** crawl a directory — pass the files you want +transpiled, optionally via a shell glob. + +### Output modes + +| Mode | Effect | +| ------------------------------ | ---------------------------------------------------------------- | +| _no output flag_ | Write the transpiled output to standard out. | +| `-o `, `--output ` | Write the output to a single file. Conflicts with `--outdir`. | +| `--outdir ` | Write each input file into ``, mirroring the source layout. | + +```sh +# Print to stdout +deno transpile main.ts + +# Write to a single file +deno transpile main.ts -o dist/main.js + +# Transpile multiple files into an output directory +deno transpile src/main.ts src/helpers.ts --outdir dist + +# Use a shell glob +deno transpile src/*.ts --outdir dist +``` + +### Input / output extension mapping + +| Input | Output | Source map | +| ------ | ------ | ---------- | +| `.ts` | `.js` | `.js.map` | +| `.tsx` | `.js` | `.js.map` | +| `.jsx` | `.js` | `.js.map` | +| `.mts` | `.mjs` | `.mjs.map` | +| `.cts` | `.cjs` | `.cjs.map` | + +JSX transform, decorators, target, and other emit settings come from +`compilerOptions` in your `deno.json` (or `tsconfig.json`), so the output +matches what `deno run` would execute. See +[TypeScript compiler options](/runtime/fundamentals/typescript/#configuring-typescript-compiler-options) +for the full list. + +### Source maps + +Pass `--source-map` with one of: + +| Mode | Effect | +| ---------- | ------------------------------------------------------ | +| `none` | (default) no source map | +| `inline` | embed the source map as a `data:` comment in each file | +| `separate` | write a sibling `.js.map` (or `.mjs.map` / `.cjs.map`) | + +```sh +deno transpile main.ts -o dist/main.js --source-map separate +``` + +### Type declarations + +Use `--declaration` to emit `.d.ts` declaration files. Declarations are produced +by `tsc` (using the bundled TypeScript), so this flag honors the +`compilerOptions` from your `deno.json` / `tsconfig.json`. + +`.d.ts` files are always written to disk — next to the source when no output +location is set, or into `--outdir` when one is supplied — even if the +JavaScript output is going to stdout or a single `-o` file. + +```sh +deno transpile src/*.ts --outdir dist --declaration +``` + +## How it differs from `tsc` + +`deno transpile` and TypeScript's `tsc` overlap, but they aren't drop-in +replacements for each other: + +| Concern | `deno transpile` | `tsc` | +| ------------------------------ | ------------------------------------------------------ | -------------------------------- | +| **Type checking** | None — emit only. Use `deno check` separately. | Full type checking by default. | +| **`.d.ts` generation** | Yes, with `--declaration`. Delegates to bundled `tsc`. | Yes. | +| **JSR / npm / remote imports** | Resolves them. | Doesn't resolve them. | +| **Config source** | `deno.json` (or `tsconfig.json`). | `tsconfig.json` only. | +| **Speed** | Fast SWC-based emit. | Slower (type-checking included). | + +If you want type errors to surface, run +[`deno check`](/runtime/reference/cli/check/) before or after transpilation. +`deno transpile` will happily emit code that fails to type-check. + +## Caveats + +- **No bundling.** Each input file produces one output file. Imports are + rewritten extension-only (`./foo.ts` → `./foo.js`) but the resulting graph + still requires a runtime that resolves the imports. For a single-file output, + use [`deno bundle`](/runtime/reference/cli/bundle/). +- **No directory crawl.** Passing a directory does nothing — pass the files + explicitly (`src/**/*.ts`) or via a glob. +- **Source maps and stdout.** `--source-map inline` works when writing to + stdout; `separate` requires an output path it can write the map next to. + +## See also + +- [`deno bundle`](/runtime/reference/cli/bundle/) — produce a single bundled + JavaScript file +- [`deno pack`](/runtime/reference/cli/pack/) — build an npm-publishable tarball + (uses `deno transpile` internally) +- [`deno check`](/runtime/reference/cli/check/) — type-check without emitting +- [TypeScript support](/runtime/fundamentals/typescript/) — overview of how + TypeScript works in Deno diff --git a/runtime/reference/cli/upgrade.md b/runtime/reference/cli/upgrade.md index 94006d443..63b2d3e09 100644 --- a/runtime/reference/cli/upgrade.md +++ b/runtime/reference/cli/upgrade.md @@ -1,5 +1,5 @@ --- -last_modified: 2026-03-05 +last_modified: 2026-05-20 title: "deno upgrade" oldUrl: /runtime/manual/tools/upgrade/ command: upgrade @@ -88,6 +88,27 @@ on GitHub: curl -sL https://github.com/denoland/deno/releases/download/v2.7.0/deno-x86_64-unknown-linux-gnu.zip.sha256sum ``` +## Delta updates + +Starting in Deno 2.8, `deno upgrade` downloads small binary patches (deltas) +instead of the full release archive when upgrading between recent stable +versions. This typically reduces the download from tens of megabytes to a few +megabytes. + +Deltas are applied automatically when available, there is nothing to opt into. +If a patch is missing or fails verification, `deno upgrade` transparently falls +back to downloading the full archive. + +To force a full download (for example, in environments that cache release +archives) pass `--no-delta`: + +```sh +deno upgrade --no-delta +``` + +Each delta patch and the resulting binary are verified against the SHA-256 +checksums published with the release before being installed. + ## Canary build By default, Deno will upgrade from the official GitHub releases. You can specify @@ -97,3 +118,30 @@ the `--canary` build flag for the latest canary build: # Upgrade to the latest canary build deno upgrade --canary ``` + +## Install a build from a pull request + +Starting in Deno 2.8, `deno upgrade pr ` downloads the binary built by +CI for a specific deno PR and installs it. This is handy when you need to verify +a fix before it has shipped in a release. + +```sh +# Install the binary built by CI for PR #12345 +deno upgrade pr 12345 + +# A `#` prefix is also accepted +deno upgrade pr '#12345' + +# Write to a path instead of replacing the current binary +deno upgrade --output ./deno-test pr 12345 + +# See what would be downloaded without replacing +deno upgrade --dry-run pr 12345 +``` + +This subcommand requires the [`gh` CLI](https://cli.github.com/) to be installed +and authenticated. `deno upgrade` uses `gh` to look up the PR's CI run and +download the matching `{profile}-{os}-{arch}-deno` artifact (for example +`release-linux-x86_64-deno`), preferring release builds and falling back to +debug. The downloaded binary is verified to run before it replaces the current +executable. diff --git a/runtime/reference/cli/why.md b/runtime/reference/cli/why.md new file mode 100644 index 000000000..59005856f --- /dev/null +++ b/runtime/reference/cli/why.md @@ -0,0 +1,106 @@ +--- +last_modified: 2026-05-20 +title: "deno why" +command: why +openGraphLayout: "/open_graph/cli-commands.jsx" +openGraphTitle: "deno why" +description: "Explain why a package is installed by showing its dependency chains" +--- + +The `deno why` command explains why a particular package is in your dependency +tree by printing every path from your project's direct dependencies down to the +queried package. It reads the +[lockfile](/runtime/fundamentals/modules/#integrity-checking-and-lock-files), so +it works regardless of which node_modules / npm resolver mode you use and +without touching the network. + +It pairs with [`deno add`](/runtime/reference/cli/add/) and +[`deno remove`](/runtime/reference/cli/remove/): once you know _why_ a +transitive dependency is in your tree, you can decide whether to remove a direct +dependency that's pulling it in. + +## Usage + +```sh +deno why +``` + +`` is an npm or JSR package name, optionally pinned with `@`: + +| Form | Meaning | +| --------------- | -------------------------------------------- | +| `ms` | every version of `ms` in the tree | +| `ms@2.0.0` | only the `2.0.0` version | +| `@std/path` | a JSR package by its bare name | +| `jsr:@std/path` | a JSR package by its full specifier | +| `npm:express` | force npm lookup (useful when names collide) | + +## Examples + +### Multiple paths to a single package + +```sh +$ deno why ms +ms@2.0.0 + npm:express@^4.18.0 > debug@2.6.9 > ms@2.0.0 + npm:express@^4.18.0 > body-parser@1.20.4 > debug@2.6.9 > ms@2.0.0 + npm:express@^4.18.0 > finalhandler@1.3.2 > debug@2.6.9 > ms@2.0.0 + +ms@2.1.3 + npm:express@^4.18.0 > send@0.19.2 > ms@2.1.3 +``` + +When the same package appears at multiple versions, each is shown in its own +block — handy for diagnosing duplicated dependencies that bloat `node_modules`. + +### Pinned to a single version + +```sh +$ deno why ms@2.1.3 +ms@2.1.3 + npm:express@^4.18.0 > send@0.19.2 > ms@2.1.3 +``` + +### JSR packages + +```sh +$ deno why @std/path +@std/path@1.0.6 + @scope/my-lib@^1.0.0 > @std/path@1.0.6 + @std/fs@^1.0.16 > @std/path@1.0.6 +``` + +JSR packages added in Deno 2.8+ resolve the same way npm packages do — you can +pass either the bare name (`@std/path`) or the full specifier (`jsr:@std/path`). + +### Workspace members + +In a [workspace](/runtime/fundamentals/workspaces/), each member's direct +dependencies appear as roots in the output, so a transitive dep introduced by +one package is clearly attributable to that package. + +## Exit codes + +| Exit code | Meaning | +| --------- | -------------------------------------------------------------------------------------- | +| `0` | The package was found in the resolved tree — at least one dependency path was printed. | +| Non-zero | The package is not in the resolved tree, or the argument is malformed. | + +The non-zero exit is the easy way to gate CI on a package _not_ being pulled in. +For example, to assert that `left-pad` never enters your tree: + +```sh +# fails the build if left-pad is reachable +! deno why left-pad +``` + +## Common pitfalls + +- **"Package not found" but you _know_ it's used at runtime.** `deno why` + reports what's _in the lockfile_, not what's _imported by your code_. If + you've added a `npm:` or `jsr:` specifier but haven't run `deno install` (or + any subcommand that resolves), the package won't appear yet. +- **Resolution depends on workspace mode.** A package only consumed by one + workspace member may not show up when run from a different member's directory + if your workspace setup uses per-member lockfiles. Run `deno why` from the + workspace root for the complete picture. diff --git a/runtime/reference/cli/x.md b/runtime/reference/cli/x.md index 507697ea1..b588cb9c7 100644 --- a/runtime/reference/cli/x.md +++ b/runtime/reference/cli/x.md @@ -1,5 +1,5 @@ --- -last_modified: 2025-12-10 +last_modified: 2026-05-20 title: "deno x" command: x openGraphLayout: "/open_graph/cli-commands.jsx" @@ -45,6 +45,23 @@ Run a JSR package: deno x jsr:@std/http/file-server ``` +## Specifying the package separately from the binary + +Some npm packages expose multiple binaries — `typescript` ships both `tsc` and +`tsserver`, for example. Starting in Deno 2.8, `--package` (`-p`) lets you +choose the package and the binary independently, matching the +`npx -p ` convention: + +```sh +# Run `tsc` from the typescript package +deno x -p typescript tsc + +# Pin the package version +deno x -p typescript@5 tsc +``` + +The previous form `deno x typescript/tsc` still works. + ## How it works `deno x` downloads the package to the global cache (if not already cached), diff --git a/runtime/reference/continuous_integration.md b/runtime/reference/continuous_integration.md index 1e9a43712..4d03f7e8b 100644 --- a/runtime/reference/continuous_integration.md +++ b/runtime/reference/continuous_integration.md @@ -50,6 +50,11 @@ jobs: To expand the workflow, add any of the `deno` subcommands that you might need: ```yaml +# Install the locked dependencies as a single reproducible step +# (Deno 2.8+). Equivalent to `deno install --frozen` plus npm +# lifecycle-script handling — see the deno ci reference page. +- run: deno ci + # Check if the code is formatted according to Deno's default # formatting conventions. - run: deno fmt --check diff --git a/runtime/reference/docker.md b/runtime/reference/docker.md index 07cc2d76d..a428091bc 100644 --- a/runtime/reference/docker.md +++ b/runtime/reference/docker.md @@ -14,19 +14,24 @@ To use the official image, create a `Dockerfile` in your project directory: ```dockerfile FROM denoland/deno:latest -# Create working directory WORKDIR /app -# Copy source -COPY . . +# Copy manifests first so the dependency install layer caches across +# source-only edits +COPY deno.json deno.lock package.json* ./ +RUN deno ci --prod --skip-types -# Install dependencies (use just `deno install` if deno.json has imports) -RUN deno install --entrypoint main.ts +# Then copy the rest of the source +COPY . . -# Run the app CMD ["deno", "run", "--allow-net", "main.ts"] ``` +[`deno ci`](/runtime/reference/cli/ci/) performs a reproducible install from +`deno.lock`. `--prod` skips `devDependencies`, and `--skip-types` drops +`@types/*` packages — both shrink the resulting image without affecting runtime +behavior. + ### Best Practices #### Use Multi-stage Builds @@ -39,9 +44,14 @@ FROM denoland/deno:latest AS builder # Point Deno's cache at a known location so it can be copied to the next stage ENV DENO_DIR=/deno-dir WORKDIR /app + +# Copy manifests first so the dependency install layer caches across +# source-only edits +COPY deno.json deno.lock package.json* ./ +RUN deno ci --prod --skip-types + +# Then copy the rest of the source COPY . . -# Install dependencies (use just `deno install` if deno.json has imports) -RUN deno install --entrypoint main.ts # Production stage FROM denoland/deno:latest @@ -53,10 +63,9 @@ COPY --from=builder /deno-dir /deno-dir CMD ["deno", "run", "--allow-net", "main.ts"] ``` -Without copying `$DENO_DIR`, `deno install` only writes to Deno's global cache -inside the builder stage — those files do not travel with -`COPY --from=builder /app .`, so the container re-downloads dependencies on -first run. +Without copying `$DENO_DIR`, `deno ci` only writes to Deno's global cache inside +the builder stage — those files do not travel with `COPY --from=builder /app .`, +so the container re-downloads dependencies on first run. #### Permission Flags diff --git a/runtime/reference/env_variables.md b/runtime/reference/env_variables.md index 8769046bc..759c726bc 100644 --- a/runtime/reference/env_variables.md +++ b/runtime/reference/env_variables.md @@ -1,5 +1,5 @@ --- -last_modified: 2025-12-19 +last_modified: 2026-05-20 title: "Environment variables" description: "A guide to working with environment variables in Deno. Learn about Deno.env API, .env file support, CLI configuration, and special environment variables that control Deno's behavior." oldUrl: @@ -138,25 +138,27 @@ examples. The Deno runtime has these special environment variables. -| name | description | -| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DENO_AUTH_TOKENS | A semi-colon separated list of bearer tokens and hostnames to use when fetching remote modules from private repositories
(e.g. `abcde12345@deno.land;54321edcba@github.com`) | -| DENO_TLS_CA_STORE | Comma-separated list of order dependent certificate stores.
Possible values: `system`, `mozilla`. Defaults to `mozilla`. | -| DENO_CERT | Load certificate authority from PEM encoded file | -| DENO_COVERAGE_DIR | Set the directory for collecting coverage profile data. This option only works for [`deno test` subcommand](/runtime/reference/cli/test/). | -| DENO_DIR | Set the cache directory | -| DENO_INSTALL_ROOT | Set deno install's output directory (defaults to `$HOME/.deno/bin`) | -| DENO_REPL_HISTORY | Set REPL history file path History file is disabled when the value is empty
(defaults to `$DENO_DIR/deno_history.txt`) | -| DENO_NO_PACKAGE_JSON | Disables auto-resolution of `package.json` | -| DENO_NO_PROMPT | Set to disable permission prompts on access
(alternative to passing `--no-prompt` on invocation) | -| DENO_NO_UPDATE_CHECK | Set to disable checking if a newer Deno version is available | -| DENO_V8_FLAGS | Set V8 command line options | -| DENO_JOBS | Number of parallel workers used for the `--parallel` flag with the test subcommand.
Defaults to number of available CPUs. | -| DENO_KV_ACCESS_TOKEN | Personal access token used when connecting to Deno KV databases (for example via [`Deno.openKv`](/api/deno/~/Deno.openKv) or `@deno/kv` with a KV Connect URL). | -| DENO_WEBGPU_TRACE | Path to a directory to output a [WGPU trace](https://github.com/gfx-rs/wgpu/pull/619) to when using the WebGPU API | -| DENO_WEBGPU_BACKEND | Select the backend WebGPU will use, or a comma separated list of backends in order of preference. Possible values are `vulkan`, `dx12`, `metal`, or `opengl` | -| HTTP_PROXY | Proxy address for HTTP requests (module downloads, fetch) | -| HTTPS_PROXY | Proxy address for HTTPS requests (module downloads, fetch) | -| NPM_CONFIG_REGISTRY | URL to use for the npm registry. | -| NO_COLOR | Set to disable color | -| NO_PROXY | Comma-separated list of hosts which do not use a proxy (module downloads, fetch) | +| name | description | +| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DENO_AUTH_TOKENS | A semi-colon separated list of bearer tokens and hostnames to use when fetching remote modules from private repositories
(e.g. `abcde12345@deno.land;54321edcba@github.com`) | +| DENO_TLS_CA_STORE | Comma-separated list of order dependent certificate stores.
Possible values: `system`, `mozilla`. Defaults to `mozilla`. | +| DENO_CERT | Load certificate authority from PEM encoded file | +| NODE_EXTRA_CA_CERTS | Path to a PEM file with extra certificate authorities. Loaded at the root certificate store level, so the certs are honored by `fetch()`, [`Deno.connectTls()`](/api/deno/~/Deno.connectTls), and Node compat APIs (`node:https`, `node:tls`). Available in Deno 2.8+. Missing or invalid files emit a warning rather than failing, matching Node.js. | +| DENO_COVERAGE_DIR | Set the directory for collecting coverage profile data. This option only works for [`deno test` subcommand](/runtime/reference/cli/test/). | +| DENO_DIR | Set the cache directory | +| DENO_INSTALL_ROOT | Set deno install's output directory (defaults to `$HOME/.deno/bin`) | +| DENO_REPL_HISTORY | Set REPL history file path History file is disabled when the value is empty
(defaults to `$DENO_DIR/deno_history.txt`) | +| DENO_NO_PACKAGE_JSON | Disables auto-resolution of `package.json` | +| DENO_NO_PROMPT | Set to disable permission prompts on access
(alternative to passing `--no-prompt` on invocation) | +| DENO_NO_UPDATE_CHECK | Set to disable checking if a newer Deno version is available | +| DENO_V8_FLAGS | Set V8 command line options | +| DENO_JOBS | Number of parallel workers used for the `--parallel` flag with the test subcommand.
Defaults to number of available CPUs. | +| DENO_KV_ACCESS_TOKEN | Personal access token used when connecting to Deno KV databases (for example via [`Deno.openKv`](/api/deno/~/Deno.openKv) or `@deno/kv` with a KV Connect URL). | +| DENO_AUDIT_PERMISSIONS | Audit every permission access. Set to a file path to write JSONL, or to the literal value `otel` to emit OpenTelemetry log records via the configured OTel exporter. See [permissions audit](/runtime/fundamentals/security/#permission-flags) for the field set. | +| DENO_WEBGPU_TRACE | Path to a directory to output a [WGPU trace](https://github.com/gfx-rs/wgpu/pull/619) to when using the WebGPU API | +| DENO_WEBGPU_BACKEND | Select the backend WebGPU will use, or a comma separated list of backends in order of preference. Possible values are `vulkan`, `dx12`, `metal`, or `opengl` | +| HTTP_PROXY | Proxy address for HTTP requests (module downloads, fetch) | +| HTTPS_PROXY | Proxy address for HTTPS requests (module downloads, fetch) | +| NPM_CONFIG_REGISTRY | URL to use for the npm registry. | +| NO_COLOR | Set to disable color | +| NO_PROXY | Comma-separated list of hosts which do not use a proxy (module downloads, fetch) | diff --git a/runtime/reference/module_hooks.md b/runtime/reference/module_hooks.md new file mode 100644 index 000000000..8309cbcf1 --- /dev/null +++ b/runtime/reference/module_hooks.md @@ -0,0 +1,357 @@ +--- +last_modified: 2026-05-20 +title: "Module customization hooks" +description: "Customize module resolution and loading in Deno using the Node.js-compatible module.registerHooks() API. Create virtual modules, transpile custom formats, and intercept imports." +--- + +Deno supports the Node.js +[`module.registerHooks()`](https://nodejs.org/api/module.html#moduleregisterhooksoptions) +API, which lets you intercept and customize how modules are resolved and loaded. +This enables virtual modules, custom transpilation, module aliasing, and similar +use cases without modifying the importing code. The `node:module` API is part of +Deno's broader [Node.js compatibility](/runtime/fundamentals/node/) layer. + +The hooks are **synchronous** and run **in the same thread** as your +application. They work for both ES modules (`import`) and CommonJS +(`require()`). + +> Deno does not implement the asynchronous `module.register()` API. Use +> `registerHooks()` for both CommonJS and ESM customization. + +## Basic example + +```js title="main.mjs" +import { registerHooks } from "node:module"; + +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === "virtual:greet") { + return { url: "file:///virtual_greet.js", shortCircuit: true }; + } + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + if (url === "file:///virtual_greet.js") { + return { + source: 'export const msg = "hello from hooks";', + format: "module", + shortCircuit: true, + }; + } + return nextLoad(url, context); + }, +}); + +const { msg } = await import("virtual:greet"); +console.log(msg); // "hello from hooks" + +// Remove hooks when no longer needed +hooks.deregister(); +``` + +```sh +deno run --allow-all main.mjs +``` + +## Loading hooks with `--import` + +To keep your application code clean — and to make sure the hooks are installed +before anything in your program imports the modules they affect — put the +`registerHooks()` call in its own loader file and preload it with `--import` (an +alias for `--preload`). + +```js title="loader.mjs" +import { registerHooks } from "node:module"; + +registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === "virtual:greet") { + return { url: "file:///virtual_greet.js", shortCircuit: true }; + } + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + if (url === "file:///virtual_greet.js") { + return { + source: 'export const msg = "hello from loader";', + format: "module", + shortCircuit: true, + }; + } + return nextLoad(url, context); + }, +}); +``` + +```js title="main.mjs" +const { msg } = await import("virtual:greet"); +console.log(msg); // "hello from loader" +``` + +Run with `--import` pointing at the loader: + +```sh +deno run --import ./loader.mjs main.mjs +``` + +`--import` accepts multiple values, so you can compose loaders (e.g. +`--import ./aliases.mjs --import ./transpile.mjs`). They register in the order +given, which is the reverse of the order in which they run — see +[Hook chaining](#hook-chaining). The flag is available on +[`deno run`](/runtime/reference/cli/run/), +[`deno test`](/runtime/reference/cli/test/), +[`deno bench`](/runtime/reference/cli/bench/), and +[`deno serve`](/runtime/reference/cli/serve/). + +## Use cases + +### Custom transpilation + +Transform non-standard file formats on the fly: + +```js +import { registerHooks } from "node:module"; + +registerHooks({ + load(url, context, nextLoad) { + if (url.endsWith(".coffee")) { + const result = nextLoad(url, context); + const compiled = compileCoffeeScript(result.source); + return { source: compiled, format: "module", shortCircuit: true }; + } + return nextLoad(url, context); + }, +}); +``` + +### Module aliasing + +Redirect imports to different modules: + +```js +import { registerHooks } from "node:module"; + +registerHooks({ + resolve(specifier, context, nextResolve) { + // Redirect lodash to lodash-es + if (specifier === "lodash") { + return nextResolve("lodash-es", context); + } + return nextResolve(specifier, context); + }, +}); +``` + +### Virtual modules + +Create modules that exist only in memory: + +```js +import { registerHooks } from "node:module"; + +const virtualModules = new Map([ + ["virtual:config", 'export default { debug: true, version: "1.0.0" };'], + ["virtual:env", `export const NODE_ENV = "${process.env.NODE_ENV}";`], +]); + +registerHooks({ + resolve(specifier, context, nextResolve) { + if (virtualModules.has(specifier)) { + return { url: `file:///virtual/${specifier}`, shortCircuit: true }; + } + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + for (const [name, source] of virtualModules) { + if (url === `file:///virtual/${name}`) { + return { source, format: "module", shortCircuit: true }; + } + } + return nextLoad(url, context); + }, +}); +``` + +### Mocking for tests + +Replace modules with mocks during testing: + +```js +import { registerHooks } from "node:module"; + +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === "./database.js") { + return { url: "file:///mock_database.js", shortCircuit: true }; + } + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + if (url === "file:///mock_database.js") { + return { + source: 'export const query = () => [{ id: 1, name: "mock" }];', + format: "module", + shortCircuit: true, + }; + } + return nextLoad(url, context); + }, +}); + +// Run tests... + +hooks.deregister(); // Clean up after tests +``` + +## The `resolve` hook + +The `resolve` hook intercepts module resolution, mapping specifiers to URLs. + +```js +resolve(specifier, context, nextResolve); +``` + +**Parameters:** + +| Parameter | Type | Description | +| ------------- | ---------- | -------------------------------------------------- | +| `specifier` | `string` | The module specifier being resolved | +| `context` | `object` | Resolution context (see below) | +| `nextResolve` | `function` | Delegates to the next hook or the default resolver | + +**Context object:** + +| Property | Type | Description | +| ------------------ | ---------- | ------------------------------------------------------ | +| `conditions` | `string[]` | Import conditions (e.g., `["node", "import"]` for ESM) | +| `parentURL` | `string` | URL of the importing module | +| `importAttributes` | `object` | Import attributes from the import statement | + +**Return value:** + +| Property | Type | Description | +| -------------- | --------- | -------------------------------------------- | +| `url` | `string` | The resolved URL for the module | +| `shortCircuit` | `boolean` | If `true`, skip remaining hooks in the chain | + +Either call `nextResolve()` to delegate, or return a result with +`shortCircuit: true`. You must do one or the other. + +## The `load` hook + +The `load` hook intercepts module loading, providing the source code for a +resolved URL. + +```js +load(url, context, nextLoad); +``` + +**Parameters:** + +| Parameter | Type | Description | +| ---------- | ---------- | ------------------------------------------------ | +| `url` | `string` | The resolved module URL | +| `context` | `object` | Load context (see below) | +| `nextLoad` | `function` | Delegates to the next hook or the default loader | + +**Context object:** + +| Property | Type | Description | +| ------------------ | ---------- | --------------------------------------------------- | +| `format` | `string` | Module format hint (e.g., `"module"`, `"commonjs"`) | +| `conditions` | `string[]` | Import conditions | +| `importAttributes` | `object` | Import attributes | + +**Return value:** + +| Property | Type | Description | +| -------------- | -------------------------- | ------------------------------------------------- | +| `source` | `string \| Buffer \| null` | The module source code | +| `format` | `string` | Module format: `"module"`, `"commonjs"`, `"json"` | +| `shortCircuit` | `boolean` | If `true`, skip remaining hooks in the chain | + +## Deregistering hooks + +`registerHooks()` returns an object with a `deregister()` method to remove the +hooks: + +```js +const hooks = registerHooks({/* ... */}); + +// Later, remove hooks +hooks.deregister(); +``` + +## Hook chaining + +You can register multiple hooks; they form a chain. Hooks run in LIFO (last +registered, first called) order, and each hook can call `nextResolve()` / +`nextLoad()` to pass control to the previous hook in the chain: + +```js +import { registerHooks } from "node:module"; + +// Hook 1: registered first, runs second +const hook1 = registerHooks({ + load(url, context, nextLoad) { + const result = nextLoad(url, context); + if (url.includes("target.js")) { + return { + source: 'export default "from hook1"', + format: "module", + shortCircuit: true, + }; + } + return result; + }, +}); + +// Hook 2: registered second, runs first +const hook2 = registerHooks({ + load(url, context, nextLoad) { + const result = nextLoad(url, context); // Calls hook1 + if (url.includes("target.js")) { + return { + source: 'export default "from hook2"', + format: "module", + shortCircuit: true, + }; + } + return result; + }, +}); + +// Result comes from hook2 since it runs first (LIFO) +``` + +## CommonJS + +Hooks also intercept `require()`: + +```js title="main.cjs" +const { registerHooks } = require("module"); + +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === "virtual-module") { + return { url: "file:///virtual.js", shortCircuit: true }; + } + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + if (url === "file:///virtual.js") { + return { + source: "module.exports = { value: 42 }", + format: "commonjs", + shortCircuit: true, + }; + } + return nextLoad(url, context); + }, +}); + +const mod = require("virtual-module"); +console.log(mod.value); // 42 + +hooks.deregister(); +``` diff --git a/runtime/reference/web_platform_apis.md b/runtime/reference/web_platform_apis.md index 5f5c7e15d..5b57cbc42 100644 --- a/runtime/reference/web_platform_apis.md +++ b/runtime/reference/web_platform_apis.md @@ -1,5 +1,5 @@ --- -last_modified: 2025-05-09 +last_modified: 2026-05-20 title: "Web Platform APIs" description: "A guide to the Web Platform APIs available in Deno. Learn about fetch, events, workers, storage, and other web standard APIs, including implementation details and deviations from browser specifications." oldUrl: @@ -99,6 +99,55 @@ Notes on fetching local files: - Response bodies are streamed from the Rust side, so large files are available in chunks, and can be cancelled. +## Structured Clone & Transferable Objects + +Deno supports [`structuredClone()`](/api/web/~/structuredClone) and +[`postMessage()`](/api/web/~/Worker) for cloning and transferring objects across +contexts (e.g. between the main thread and Web Workers). + +### Serializable types + +These types can be cloned with `structuredClone()` and sent via `postMessage()`: + +| Type | Notes | +| ----------------------------------------- | -------------------------------------------------------------------------------------------- | +| Primitives | `string`, `number`, `boolean`, `null`, `undefined`, `bigint` | +| `Array`, `Object`, `Map`, `Set` | Including nested structures and circular references | +| `Date`, `RegExp` | | +| `ArrayBuffer`, `TypedArray`, `DataView` | Copied by default, or transferred (see below) | +| `Error` types | `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, `URIError` | +| [`Blob`](/api/web/~/Blob) | Requires Deno 2.8+ | +| [`File`](/api/web/~/File) | Requires Deno 2.8+ | +| [`DOMException`](/api/web/~/DOMException) | | +| [`CryptoKey`](/api/web/~/CryptoKey) | | + +### Transferable types + +These types can be _transferred_ (not copied) via the `transfer` option in +`structuredClone()` or the `transfer` list in `postMessage()`. After transfer, +the original object becomes unusable: + +| Type | Notes | +| ----------------------------------------------- | ---------------------------------------- | +| [`ArrayBuffer`](/api/web/~/ArrayBuffer) | Moves the backing memory to the receiver | +| [`MessagePort`](/api/web/~/MessagePort) | Transfers the port to another context | +| [`ReadableStream`](/api/web/~/ReadableStream) | Transfers the stream to another context | +| [`WritableStream`](/api/web/~/WritableStream) | Transfers the stream to another context | +| [`TransformStream`](/api/web/~/TransformStream) | Transfers the stream to another context | + +```ts +// Clone a Blob +const blob = new Blob(["hello"], { type: "text/plain" }); +const cloned = structuredClone(blob); +console.log(await cloned.text()); // "hello" + +// Transfer an ArrayBuffer through a MessageChannel +const buffer = new ArrayBuffer(1024); +const ch = new MessageChannel(); +ch.port1.postMessage(buffer, [buffer]); +// buffer.byteLength is now 0 (transferred) +``` + ## CustomEvent and EventTarget The [DOM Event API](/api/web/~/Event) can be used to dispatch and listen to @@ -489,6 +538,83 @@ const worker = new Worker(import.meta.resolve("./worker.js"), { }); ``` +## OffscreenCanvas + +Starting in Deno 2.8, the +[`OffscreenCanvas`](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas) +API is available. `OffscreenCanvas` is a canvas that lives outside any DOM and +can be used anywhere (including Web Workers) for off-thread rendering and image +generation. + +### Supported rendering contexts + +`OffscreenCanvas#getContext` accepts two of the spec-defined context ids: + +- `"bitmaprenderer"`: returns an + [`ImageBitmapRenderingContext`](https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmapRenderingContext) + for displaying an `ImageBitmap` produced via `createImageBitmap`. +- `"webgpu"`: returns a + [`GPUCanvasContext`](https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext) + for rendering with WebGPU. + +Calling `getContext` with `"2d"`, `"webgl"`, or `"webgl2"` returns `null`; these +contexts are not implemented in Deno. + +### Example: encoding an image to PNG + +Decode an image into an `ImageBitmap`, place it on an `OffscreenCanvas` via the +`bitmaprenderer` context, and write the result to disk: + +```ts +const data = await Deno.readFile("./input.jpg"); +const bitmap = await createImageBitmap(new Blob([data])); + +const canvas = new OffscreenCanvas(bitmap.width, bitmap.height); +const ctx = canvas.getContext("bitmaprenderer")!; +ctx.transferFromImageBitmap(bitmap); + +const blob = await canvas.convertToBlob({ type: "image/png" }); +await Deno.writeFile( + "./output.png", + new Uint8Array(await blob.arrayBuffer()), +); +``` + +Typical uses: + +- producing thumbnails, format conversions, or social-card images at request + time without spinning up a headless browser, +- running off-thread image work inside a Web Worker, +- driving WebGPU rendering targets that don't need a window. + +## Geometry Interfaces + +Starting in Deno 2.8, the +[Geometry Interfaces Module Level 1](https://drafts.fxtf.org/geometry/) types +are available as globals. These are the same types you'd find in a browser: + +- [`DOMMatrix`](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix) / + [`DOMMatrixReadOnly`](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnly): + 4×4 transform matrices for 2D and 3D operations. +- [`DOMPoint`](https://developer.mozilla.org/en-US/docs/Web/API/DOMPoint) / + [`DOMPointReadOnly`](https://developer.mozilla.org/en-US/docs/Web/API/DOMPointReadOnly): + points in 2D / 3D space. +- [`DOMRect`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) / + [`DOMRectReadOnly`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly): + axis-aligned rectangles. +- [`DOMQuad`](https://developer.mozilla.org/en-US/docs/Web/API/DOMQuad): a + quadrilateral defined by four points. + +```ts +const m = new DOMMatrix().translateSelf(10, 20).scaleSelf(2); +const p = new DOMPoint(1, 1).matrixTransform(m); +console.log(p.x, p.y); // 12 22 +``` + +These types are useful for graphics work; applying transforms to canvas +drawings, computing layout math, or porting browser code that depends on +geometry types. + ## Deviations of other APIs from spec ### Cache API @@ -498,9 +624,13 @@ Only the following APIs are implemented: - [CacheStorage::open()](https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage/open) - [CacheStorage::has()](https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage/has) - [CacheStorage::delete()](https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage/delete) +- [CacheStorage::keys()](https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage/keys) + (Deno 2.8+) - [Cache::match()](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) - [Cache::put()](https://developer.mozilla.org/en-US/docs/Web/API/Cache/put) - [Cache::delete()](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete) +- [Cache::keys()](https://developer.mozilla.org/en-US/docs/Web/API/Cache/keys) + (Deno 2.8+) A few things that are different compared to browsers: