# Deno 2.7: Temporal API, Windows ARM, and npm overrides

> Source: <https://deno.com/blog/v2.7>
> Published: 2026-02-25 09:00:00+00:00

We are happy to announce the release of version 2.7 of the Deno runtime, which brings a number of improvements and additions.

To upgrade to Deno 2.7, run the following in your terminal:

```
deno upgrade
```

If Deno is not yet installed, run one of the following commands to install or
[learn how to install it here](https://docs.deno.com/runtime/manual/getting_started/installation).

```
# Using Shell (macOS and Linux):
curl -fsSL https://deno.land/install.sh | sh

# Using PowerShell (Windows):
iwr https://deno.land/install.ps1 -useb | iex
```

What’s new in Deno 2.7

`Temporal`

API stabilized[Windows on ARM support](#windows-on-arm-support)`package.json`

overrides support`Deno.spawn()`

and friends (unstable)[Node.js compatibility](#nodejs-compatibility)[API changes](#api-changes)[Quality of life improvements](#quality-of-life-improvements)[V8 14.5](#v8-14-5)[Acknowledgments](#acknowledgments)

`Temporal`

API stabilized

The [ Temporal API](https://tc39.es/proposal-temporal/docs/) is now stable in
Deno. The

`--unstable-temporal`

flag is no longer required. Chrome 144 shipped
`Temporal`

in January 2026, and Deno now follows suit as part of the
[V8 14.5 upgrade](#v8-14-5).

``` js
const today = Temporal.Now.plainDateISO();
const nextMonth = today.add({ months: 1 }); // immutable - today unchanged

const meeting = Temporal.ZonedDateTime.from(
  "2026-03-15T14:30[America/New_York]",
);
const inTokyo = meeting.withTimeZone("Asia/Tokyo"); // same instant
```

For a deeper dive, see
[Mat’s fantastic post](https://piccalil.li/blog/date-is-out-and-temporal-is-in/).

Windows on ARM support

Deno now provides official builds for Windows on ARM
(`aarch64-pc-windows-msvc`

). This means native performance on ARM-based Windows
devices like Surface Pro X, Lenovo ThinkPad X13s, and other Snapdragon-powered
laptops, with no x86 emulation overhead.

```
# Install Deno on Windows ARM
iwr https://deno.land/install.ps1 -useb | iex
```

This has been a
[long](https://github.com/denoland/deno/issues/8422)-[requested](https://github.com/denoland/deno/issues/13331)
feature and closes the gap for developers working on ARM hardware across all
major platforms.

`package.json`

overrides support

Deno has
[first-class package.json support](https://docs.deno.com/runtime/fundamentals/node/#first-class-package.json-support).
Our goal is that Node projects run in Deno with little to no changes. This
release adds support for the

[field, giving you control over the versions of packages deep in your dependency tree.](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides)

`overrides`

This is useful when you need to pin a transitive dependency to fix a security vulnerability, force compatibility with a specific version, or replace a package entirely.

```
{
  "dependencies": {
    "express": "^4.18.0"
  },
  "overrides": {
    "cookie": "0.7.0",
    "express": {
      "qs": "6.13.0"
    }
  }
}
```

In this example, `cookie`

is pinned to `0.7.0`

everywhere in the dependency
graph, while `qs`

is only overridden when required by `express`

.

New APIs for subprocesses

Deno 2.7 introduces a simpler way to run subprocesses. The new `Deno.spawn()`

,
`Deno.spawnAndWait()`

, and `Deno.spawnAndWaitSync()`

functions are convenient
shorthands for the existing `Deno.Command`

API:

``` js
// Before: two steps
const child = new Deno.Command("echo", { args: ["hello"] }).spawn();

// After: one step
const child = Deno.spawn("echo", ["hello"]);
```

All three functions support a 3-argument overload where args are passed separately from options:

``` js
// Spawn a child process (returns ChildProcess)
const child = Deno.spawn("deno", ["fmt", "--check"], {
  stdout: "inherit",
});

// Wait for completion (returns CommandOutput)
const output = await Deno.spawnAndWait("git", ["status"]);
console.log(output.stdout);

// Synchronous variant
const result = Deno.spawnAndWaitSync("echo", ["done"]);
```

These new APIs are currently marked as unstable, meaning that they may evolve over time until formally stabilised in the runtime.

Node.js compatibility

Dozens of fixes across `node:worker_threads`

, `node:child_process`

, `node:zlib`

,
`node:sqlite`

, and more.

`node:worker_threads`

- Worker stdout is now forwarded to the parent process
(
[#32160](https://github.com/denoland/deno/pull/32160)) - Worker stdin support (
[#32165](https://github.com/denoland/deno/pull/32165)) `worker.terminate()`

now returns the correct exit code ([#32168](https://github.com/denoland/deno/pull/32168))`process.exit()`

in a worker immediately halts execution ([#32169](https://github.com/denoland/deno/pull/32169))- Exit code propagation fixed
(
[#32124](https://github.com/denoland/deno/pull/32124)) `ref()`

/`unref()`

is now idempotent like Node.js ([#32161](https://github.com/denoland/deno/pull/32161))`execArgv`

validation instead of rejecting all flags ([#32145](https://github.com/denoland/deno/pull/32145))- Error events emitted for terminal errors
(
[#32052](https://github.com/denoland/deno/pull/32052)) `threadName`

property added ([#32072](https://github.com/denoland/deno/pull/32072))`worker.cpuUsage()`

implemented ([#32050](https://github.com/denoland/deno/pull/32050))`BroadcastChannel`

ref/unref support ([#32036](https://github.com/denoland/deno/pull/32036))

`node:child_process`

- stdio streams are now proper
`Socket`

instances ([#31975](https://github.com/denoland/deno/pull/31975)) - stdio streams unrefed by default to match Node.js behavior
(
[#32071](https://github.com/denoland/deno/pull/32071)) - Shell redirections handled in
`exec`

([#32087](https://github.com/denoland/deno/pull/32087)) `fork()`

now accepts`URL`

as modulePath ([#32268](https://github.com/denoland/deno/pull/32268))`timeout`

and`killSignal`

support for`spawn()`

([#32283](https://github.com/denoland/deno/pull/32283))`NODE_OPTIONS`

respected for`--require`

and`--inspect-publish-uid`

([#31949](https://github.com/denoland/deno/pull/31949))

`node:zlib`

- Zstd compression support added
(
[#32025](https://github.com/denoland/deno/pull/32025)) - Multiple compatibility fixes
(
[#32039](https://github.com/denoland/deno/pull/32039)) - Write callback is now async to match Node.js behavior
(
[#32130](https://github.com/denoland/deno/pull/32130))

`node:sqlite`

`DatabaseSync.setAuthorizer()`

implemented ([#32009](https://github.com/denoland/deno/pull/32009))- Defensive option enabled on
`DatabaseSync`

([#32004](https://github.com/denoland/deno/pull/32004)) `SQLTagStore`

implemented ([#31945](https://github.com/denoland/deno/pull/31945))`StatementSync`

compatibility improvements ([#31941](https://github.com/denoland/deno/pull/31941))- Garbage collection no longer invalidates associated resources
(
[#31737](https://github.com/denoland/deno/pull/31737))

Other changes

`PerformanceObserver`

implemented ([#31875](https://github.com/denoland/deno/pull/31875))`process.constrainedMemory()`

added ([#32209](https://github.com/denoland/deno/pull/32209))`process.features`

properly implemented ([#31864](https://github.com/denoland/deno/pull/31864))`hasColors()`

added to`process.stdout`

and`process.stderr`

([#31985](https://github.com/denoland/deno/pull/31985))`util.parseEnv`

and`process.loadEnvFile`

compatibility ([#32183](https://github.com/denoland/deno/pull/32183))`tls.setDefaultCACertificates`

support ([#31522](https://github.com/denoland/deno/pull/31522))`inspector.open()`

,`inspector.close()`

, and`inspector.url()`

support ([#31898](https://github.com/denoland/deno/pull/31898),[#31705](https://github.com/denoland/deno/pull/31705))`fs.writeFile`

and`FileHandle.writeFile`

compatibility ([#32077](https://github.com/denoland/deno/pull/32077))`fs.rmdir`

compatibility ([#32144](https://github.com/denoland/deno/pull/32144))`fs.rm`

no longer dereferences symlinks ([#31886](https://github.com/denoland/deno/pull/31886))`openAsBlob`

export added to`node:fs`

([#32261](https://github.com/denoland/deno/pull/32261))- IPv6 host support in
`node:http`

([#32258](https://github.com/denoland/deno/pull/32258)) `AsyncLocalStorage`

context preserved in`unhandledRejection`

handlers ([#32264](https://github.com/denoland/deno/pull/32264))- Error formatting compatibility
(
[#31970](https://github.com/denoland/deno/pull/31970)) `assert.ok`

compatibility ([#32173](https://github.com/denoland/deno/pull/32173))`performance.clearResourceTimings()`

and`setResourceTimingBufferSize()`

implemented ([#31603](https://github.com/denoland/deno/pull/31603))`FileHandle.readableWebStream()`

implemented ([#31745](https://github.com/denoland/deno/pull/31745))`FileHandle.readv()`

method added ([#31943](https://github.com/denoland/deno/pull/31943))- HTTP keepAlive connection reuse is now enabled for
`node:http`

Agent, reducing latency for repeated requests to the same host ([#31709](https://github.com/denoland/deno/pull/31709)) `node:test`

mock API implemented ([#31954](https://github.com/denoland/deno/pull/31954))- Named pipe listen, connect, and open support
(
[#31624](https://github.com/denoland/deno/pull/31624))

API changes

`navigator.platform`

The `navigator.platform`

property is now available in Deno, returning the
operating system platform the runtime is running on. This improves compatibility
with web code and libraries that check `navigator.platform`

for
platform-specific behavior:

```
console.log(navigator.platform);
// "MacIntel", "Win32", "Linux x86_64", etc.
```

Brotli support in `CompressionStream`

and `DecompressionStream`

The web standard `CompressionStream`

and `DecompressionStream`

APIs now support
the `"brotli"`

format alongside the existing `"gzip"`

and `"deflate"`

:

``` js
const stream = new CompressionStream("brotli");
const response = new Response(body.pipeThrough(stream));
```

Brotli typically achieves better compression ratios than gzip for text content.

`FsFile.tryLock()`

A new non-blocking file lock method. Unlike `lock()`

which blocks until the lock
is acquired, `tryLock()`

returns immediately with a boolean indicating whether
the lock was obtained:

``` js
const file = await Deno.open("data.db", { read: true, write: true });

if (await file.tryLock(true)) {
  // Exclusive lock acquired, safe to write
  await file.write(data);
  await file.unlock();
} else {
  console.log("File is locked by another process");
}
```

SHA3 support in `crypto.subtle`

The Web Crypto API now supports SHA3 hash algorithms (`SHA3-256`

, `SHA3-384`

,
`SHA3-512`

) for `generateKey`

, `encrypt`

, and `decrypt`

operations with
RSA-OAEP:

``` js
const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA3-256",
  },
  true,
  ["encrypt", "decrypt"],
);

const data = new TextEncoder().encode("Hello, Deno!");
const encrypted = await crypto.subtle.encrypt(
  { name: "RSA-OAEP" },
  keyPair.publicKey,
  data,
);
const decrypted = await crypto.subtle.decrypt(
  { name: "RSA-OAEP" },
  keyPair.privateKey,
  encrypted,
);
```

GIF and WebP support for `createImageBitmap`

`createImageBitmap`

now supports GIF and WebP image formats in addition to the
previously supported PNG, JPEG, and BMP:

``` js
const res = await fetch("https://example.com/animation.webp");
const blob = await res.blob();
const bitmap = await createImageBitmap(blob);
console.log(`${bitmap.width}x${bitmap.height}`);
```

Package manager improvements

`deno create`

Deno supported scaffolding projects from templates using `deno init`

subcommand.
This release adds a familiar `deno create`

alias users might be familiar from
other package managers.

``` bash
# From npm (resolves to create-vite)
$ deno create npm:vite -- my-project
```

It works with JSR packages as well - as long as the JSR package exports a
`./create`

entry point, you can use it as a template source:

``` bash
# From JSR (uses the ./create export)
$ deno create jsr:@std/http
```

`deno install --compile`

You can now compile npm packages into standalone executables during global installation. Compiled executables are faster to start and don’t depend on a Deno installation:

``` bash
$ deno install --global --compile -A npm:@anthropic-ai/claude-code
```

This produces a native binary that can be distributed and run without Deno .

`--save-exact`

for `deno add`

By default, `deno add`

saves dependencies with a caret range (`^`

), allowing
compatible updates. The new `--save-exact`

(or `--exact`

) flag pins to the exact
version instead. Useful when you need to pin a specific version or are working
in environments where even minor version bumps need to be deliberate:

``` bash
$ deno add --save-exact npm:express
# Adds "express": "4.21.0" instead of "express": "^4.21.0"
```

This also works with `deno install`

.

`jsr:`

scheme support in `package.json`

You can now use `jsr:`

specifiers directly in your `package.json`

dependencies.
This means projects using `package.json`

can depend on JSR packages without
needing a `deno.json`

:

```
{
  "dependencies": {
    "@std/path": "jsr:^1.0.9"
  }
}
```

This works with `deno install`

and brings JSR packages to any project that uses
`package.json`

for dependency management.

`deno audit --ignore`

You can now filter out known advisories by CVE ID when running `deno audit`

.
This is useful for suppressing false positives or accepted risks in CI:

``` bash
$ deno audit --ignore=CVE-2024-12345,CVE-2024-67890
```

Quality of life improvements

`deno compile --self-extracting`

`deno compile`

gains a `--self-extracting`

flag. Instead of serving files from
an in-memory virtual file system, the compiled binary extracts all embedded
files to disk on first run and uses real file system operations at runtime.

This unlocks full Node API support for compiled binaries, including native
addons that need real files on disk. The extraction directory is chosen
automatically: next to the binary if writable, otherwise in the platform’s data
directory (`~/.local/share/`

on Linux, `~/Library/Application Support/`

on
macOS, `%LOCALAPPDATA%`

on Windows):

``` bash
$ deno compile --self-extracting -A main.ts -o my-app
$ ./my-app  # Extracts embedded files on first run, then executes
```

`deno task`

improvements

Deno’s built-in task runner shell becomes more configurable in this release. You
can now turn on `pipefail`

:

```
{
  "tasks": {
    "lint": "set -o pipefail && deno lint **/*.ts | tee lint-output.txt"
  }
}
```

You can also control glob behavior with `shopt`

: `nullglob`

, `failglob`

, and
`globstar`

are all configurable.

Additionally, we turned off `failglob`

by default in order to match bash’s
defaults. `failglob`

caused too many issues. For example, urls with query
parameters would cause an error due to `?`

not matching a file on the file
system.

`deno check --check-js`

If you have a JavaScript-only project and want to type-check it with Deno, you
previously had to either add `// @ts-check`

to every file or set
`compilerOptions.checkJs`

in your `deno.json`

. The new `--check-js`

flag lets
you do it in a single command with no config changes:

``` bash
$ deno check --check-js main.js
```

Fail fast for `deno fmt`

Stop on the first unformatted file instead of reporting all of them. Useful in large codebases in CI where you just need to know if something is off.

``` bash
$ deno fmt --check --fail-fast
```

Chrome DevTools and VSCode debugging improvements

Deno 2.7 brings significant improvements to the debugging experience. You can
now debug Web Workers through both Chrome DevTools and VSCode. Previously only
the main thread was debuggable. The implementation supports Chrome’s `Target.*`

domain and VSCode’s `NodeWorker.*`

domain, so workers appear automatically in
whichever debugger you use.

The `--inspect`

flag now accepts bare hosts and bare ports, matching Node.js
behavior:

``` bash
$ deno run --inspect=9229 main.ts         # 127.0.0.1:9229
$ deno run --inspect=192.168.0.1 main.ts  # 192.168.0.1:9229
$ deno run --inspect=:0 main.ts           # OS-assigned port
```

A new `--inspect-publish-uid`

flag has also been added to support VSCode’s
debugging infrastructure, allowing VSCode to use the same debugging setup for
both Node.js and Deno projects.

`deno upgrade`

cache

Downloaded Deno binaries are now cached under `$DENO_DIR/dl/`

during
`deno upgrade`

. If you upgrade to the same version again (e.g. on a different
machine profile or after a rollback), the cached archive is reused instead of
re-downloading. For canary builds, old cache entries are automatically pruned,
keeping only the 10 most recent.

If the cache grows too large, `deno clean`

will remove it along with other
cached data.

OpenTelemetry for Deno Cron

`Deno.cron`

jobs are now automatically instrumented with OpenTelemetry. Each
cron invocation emits spans with the job name and execution status, so you get
observability out of the box when using an OTEL-compatible backend.

`deno upgrade`

checksum verification

You can now verify a `deno upgrade`

download against a known checksum using the
new `--checksum`

flag. This is useful for CI pipelines and security-conscious
environments where you want to ensure the binary hasn’t been tampered with:

``` bash
$ deno upgrade --checksum=<sha256-hash> 2.7.0
```

SHA-256 checksums for each platform are published as `.sha256sum`

files
alongside the release archives on the
[GitHub releases page](https://github.com/denoland/deno/releases). You can fetch
the checksum for your platform like this:

``` bash
# Fetch the SHA-256 checksum for Linux x86_64
$ curl -sL https://github.com/denoland/deno/releases/download/v2.7.0/deno-x86_64-unknown-linux-gnu.zip.sha256sum
```

`SSLKEYLOGFILE`

support

Set the `SSLKEYLOGFILE`

environment variable to log TLS session keys to a file,
enabling traffic inspection with tools like Wireshark for debugging encrypted
connections:

``` bash
$ SSLKEYLOGFILE=./keys.log deno run --allow-net main.ts
# Now open keys.log in Wireshark to decrypt captured TLS traffic
```

V8 14.5

Deno 2.7 upgrades the V8 engine to version 14.5, bringing the latest performance improvements, bug fixes, and new JavaScript features from the V8 team.

Acknowledgments

We couldn’t build Deno without the help of our community! Whether by answering
questions in our community [Discord server](https://discord.gg/deno) or
[reporting bugs](https://github.com/denoland/deno/issues), we are incredibly
grateful for your support. In particular, we’d like to thank the following
people for their contributions to Deno 2.7: Amol Yadav, Andy Bodnar, AprilNEA,
Asher Gomez, Ayu, Bedis Nbiba, Chase Knowlden, Christian Svensson, cui,
ddmoney420, Florian Schwalm, Gitoffthelawn, Hajime-san, Haruto, intelliking,
iownbey, it-education-md, James Bronder, Jeff Wilson, John Downey, Jose
Fernandez, kantrolv, Kenta Moriuchi, kookyleo, Kyle Tse, Lee Dogeon, lif, Mahesh
Thakur, Mert Can Altin, MkDev11, Padraic Slattery, Pietro Marchini, Ramnivas
Laddad, Ryan Lahman, scarf, Takuro Kitahara, TarikSogukpinar, Tu Shaokun, ud2,
and Varun Chawla.

Would you like to join the ranks of Deno contributors?
[Check out our contribution docs here](https://docs.deno.com/runtime/manual/references/contributing),
and we’ll see you on the list next time.

Believe it or not, the changes listed above still don’t tell you everything that
got better in 2.7. You can view the
[full list of pull requests merged in Deno 2.7 on GitHub](https://github.com/denoland/deno/releases/tag/v2.7.0).

Thank you for catching up with our 2.7 release, and we hope you love building with Deno!
