Daniel Murillo
Index

Architecture · October 28, 2026 · Daniel Murillo

Deno in 2026: security, TypeScript, and a new way to run JavaScript

Deno makes sense when permissions, web APIs, and integrated tooling solve real needs. Node compatibility has advanced, but you must verify it.

Deno makes sense when its permission model, web APIs, and integrated tooling solve real needs. Its Node compatibility has advanced, but it must be verified against each project’s dependencies.

Introduction: what if the runtime also helped limit the blast radius?

Deno emerged as an alternative to Node.js with a different philosophy: security through permissions, modern web APIs, direct TypeScript, and an integrated set of tools. The idea was not only to run JavaScript faster, but to reduce some of the complexities and risks of backend development.

With Deno 2, the story evolved. The runtime added broader compatibility with npm packages and Node APIs, support for projects with package.json, and migration improvements from existing ecosystems. In Deno 2.9, published in June 2026, the team highlighted compatibility with Node.js 26, support for lockfiles from several managers, and performance improvements.

That changes the question. Deno should no longer be evaluated only as a new environment that forces you to rewrite everything: it can also be a platform for running modern applications with a different permission model.

The important question is: when do its design principles outweigh ecosystem and operational differences?

1. What is Deno?

Deno is a JavaScript and TypeScript runtime based on V8. It includes tools to run code, check types, format, lint, test, run tasks, and manage dependencies.

Among its components and capabilities are:

  • JavaScript/TypeScript runtime.
  • Web APIs such as fetch, Request, Response, URL, and streams.
  • Explicit permissions for system access.
  • deno check, deno fmt, deno lint, and deno test.
  • Package management and npm compatibility (including reading lockfiles from npm, pnpm, Yarn, and Bun in Deno 2.9).
  • The JSR registry and remote dependency support.
  • Deno.serve() for HTTP.
  • Audit and task tools.
  • Since Deno 2.9, deno desktop to package a web UI + Deno logic into a desktop binary (webview), without the typical Electron boilerplate.

deno desktop does not automatically turn Deno into a substitute for Electron for every app: evaluate packaging, system APIs, updates, and distribution. But it does expand the map of use cases beyond APIs and CLIs.

2. The permission model: security by default

In Node.js, code running inside a process usually has access to the filesystem, network, and environment variables according to the operating-system user’s permissions. Deno adopts a different model: the program does not receive unrestricted access to sensitive resources by default.

For example, a service can receive network permission only for a host, read access to a specific directory, and permission to read a specific environment variable.

# Allow network access only to the specified host
deno run --allow-net=api.example.com main.ts

# Allow reading only one folder
deno run --allow-read=./data main.ts

# Allow access to a specific environment variable
deno run --allow-env=API_KEY main.ts

This makes it easier to apply least privilege in scripts, tools, and services. It also makes more visible which resources a program needs.

What the model does not do

Permissions do not automatically turn Deno into a perfect sandbox for fully hostile code. Modules running in the same thread share the process privilege level. Granting permissions to run child processes or load native libraries widens the risk considerably. And runtime permissions do not replace dependency audits or operating-system controls.

The model is a useful layer, not a substitute for containers, isolation, dependency review, and secure deployment practices.

Source: Deno — Security and permissions

When does it add value?

  • Scripts that access files or the network.
  • Internal tools that run code from multiple sources.
  • Services that can be limited to a small set of resources.
  • Teams that want to make execution permissions explicit.
  • Automation and CI processes where reducing accidental access is a goal.

In an application where the container already applies strict limits, the additional value depends on the threat you are trying to mitigate and how permissions are administered.

3. TypeScript and integrated tools

Deno lets you run TypeScript without configuring an external transpiler for the common case. In addition, its tooling includes static checking, formatter, linter, tests, tasks, and coverage/documentation tools.

Example of a Hono service:

import { Hono } from "hono";

const app = new Hono();

app.get("/health", (context) => {
  return context.json({ status: "ok" });
});

Deno.serve(app.fetch);

In this example, the code uses TypeScript and web APIs, and Deno’s native server receives Hono’s handler.

Running and checking are different things

One advantage of Deno is that it can integrate type-checking via deno check. A typical pipeline can include:

deno fmt --check
deno lint
deno check main.ts
deno test

The concrete configuration depends on the project and version, but the principle is clear: the ease of running TypeScript does not remove the need to check types, tests, and contracts.

Are integrated tools always better?

Not necessarily. Integration can reduce friction and configuration differences. But a team may already have a consolidated stack with other tools and not get enough benefit from changing it. The goal is to reduce real complexity, not replace tools for sport.

4. Deno 2 and Node.js compatibility

One of Deno’s most important transformations is its evolution toward compatibility with npm and Node APIs.

Deno 2 supports package.json, npm packages, and a growing set of node: modules. Deno 2.9, published on June 25, 2026, updated its compatibility target toward Node.js 26 and added direct reading of npm, pnpm, Yarn, and Bun lockfiles in the install command.

Source: Deno 2.9

That lowers the adoption barrier, but broad compatibility does not mean perfect compatibility. You must verify:

  • Node APIs used by dependencies;
  • native modules and Node-API;
  • install scripts;
  • tools that inspect node_modules;
  • worker and child-process behavior;
  • cloud SDKs and database clients;
  • APM, tracing, and profiling;
  • packages that assume a specific manager or module system.

Do not take a general compatibility claim as a guarantee for your application. The decisive test is the project’s dependency matrix.

A reasonable migration

Start with a small service or an internal tool. Run the full tests, review the required permissions, and check the deploy. If the project depends on a large number of Node integrations, evaluate the cost of each incompatibility before changing the default runtime.

Documentation: Deno — Node and npm compatibility

5. Web APIs and portability

Deno relies on well-known web APIs: fetch, Request, Response, Headers, URL, and streams. That makes it easier to build services that depend less on Node-specific modules.

Hono is an interesting example because it supports Node.js, Bun, and Deno. An application that uses its portable APIs can have less runtime coupling, although dependencies, deployment, and system APIs can still introduce differences.

Portability does not happen by magic. It helps to:

  • keep business logic separate from runtime APIs;
  • use clear interfaces and contracts for database and external-service access;
  • avoid importing runtime-specific APIs in every module;
  • run tests on each runtime you actually intend to support;
  • review third-party dependency compatibility.

Portability is only useful if the team is going to use it. If the product is tied to a concrete platform, it is not worth paying an extra cost only for a hypothetical possibility.

6. Frameworks for Deno

Hono

Hono offers an interface based on web APIs and runs on Deno. It can be an option for APIs that want to keep a portable architecture across runtimes.

import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => c.text("Hello from Deno"));

Deno.serve(app.fetch);

Source: Hono — Deno

Fresh

Fresh is associated with the Deno ecosystem and focuses on web applications with server rendering and an islands-centered architecture. It is an option to evaluate when the goal is not only a REST API, but a web application.

Source: Fresh

Oak

Oak is a middleware framework inspired by Koa and traditional within the Deno ecosystem. It can be relevant for teams that already have Deno applications built in that style.

Source: Oak

Express and other npm frameworks

Deno 2 can run many npm packages, but you should not assume that any Express, NestJS, or Fastify application works without adjustments. Adapters, native modules, plugins, and auxiliary tools must be validated individually.

The framework choice should respond to the architecture and capabilities the project needs, not only to the fact that the runtime can execute it.

7. Deno 2.9 benchmarks

Deno 2.9 published improvements in startup, memory, and HTTP throughput. In the Deno.serve test, the team measured three scenarios with concurrency 100: a text response, a 1 MiB response, and a “realworld” request that receives JSON with a bearer token and returns it as JSON. The published comparison is Deno 2.8 versus Deno 2.9, on a dedicated Linux x86_64 machine.

MetricDeno 2.8Deno 2.9Reported change
Cold start34.2 ms17.3 ms1.98× faster
HTTP realworld56.8k req/s72.4k req/s1.27×
HTTP text77.0k req/s85.6k req/s1.11×
1 MiB response1 617 req/s1 907 req/s1.18×
RSS, realworld142 MB64 MB2.2× less memory
RSS, 1 MiB response197 MB63 MBsignificant reduction

Source: Deno 2.9 — Performance

What the data tell us

These numbers demonstrate a Deno improvement between versions in the selected scenarios. They do not by themselves prove that Deno is faster than Node or Bun in any application.

To compare runtimes, you need a common test with the same operations, dependencies, hardware, configuration, versions, and tools. You also need to measure latency percentiles, CPU, memory, errors, and behavior under sustained load.

Benchmarks published by Bun

Bun’s benchmarks page also includes Deno 2.9.5 in Express-over-HTTPS, PostgreSQL, and WebSockets tests. For example, in its Express 5.2.1 over TLS 1.3 test, Deno reports 19 243 req/s and 176 MB peak RAM; Bun and Node appear with different results in the same configuration.

Those data are useful as another reference, but they come from Bun’s site and must be interpreted with the methodology and code the project publishes. The PostgreSQL test, moreover, uses a different client on Bun, so it does not isolate the runtime.

Source: Bun — benchmarks

8. Security does not automatically mean more performance

Deno offers a built-in permission model that can reduce accidental access to resources. That can improve the security posture, but it does not guarantee a faster application.

Permissions also require operational work:

  • define the resources needed per environment;
  • review granted flags and permissions;
  • manage secrets without exposing them;
  • test scripts and tasks in CI;
  • avoid broad permissions when scoped ones suffice;
  • review the effect of child processes and native libraries.

Security is a property of the whole system. The runtime can provide controls, but the application needs input validation, safe secret handling, updates, OS isolation, network controls, and observability.

9. When to choose Deno?

I would evaluate it first when…

  • explicit permissions are part of the security requirements;
  • the project is new and can use standard web APIs;
  • TypeScript, linting, testing, and integrated tooling are valued;
  • Hono or another compatible library meets the requirements;
  • you want to reduce coupling to Node-specific APIs;
  • the project’s dependencies can be validated on Deno.

I would be more conservative when…

  • the application depends on native modules or Node internals;
  • a vendor only officially supports Node.js;
  • observability or auxiliary processes have specific dependencies;
  • the organization already has a mature pipeline and the benefit of changing is small;
  • the migration implies operational risk greater than the value of permissions or tooling.

10. Checklist for evaluating Deno

  • Identify Node APIs and native modules used by the project.
  • Test npm dependencies, SDKs, ORM, and database drivers.
  • Define minimum permissions for files, network, environment, and subprocesses.
  • Run formatter, linter, type-checker, and tests in CI.
  • Validate OpenTelemetry, APM, profiling, and logs.
  • Test Docker, health checks, signals, and shutdown.
  • Measure startup, throughput, p95/p99 latency, memory, and CPU.
  • Run a representative load test.
  • Define gradual deploy and rollback.
  • Document the differences the team must maintain.

Conclusion

Deno combines direct TypeScript, integrated tools, web APIs, and an explicit permission model. Its npm and Node compatibility has improved enough that it also deserves evaluation as a platform for existing projects, not only for new applications.

Its advantages are especially relevant when the team wants explicit permissions, an integrated development flow, and less dependence on Node-specific APIs. Its main caution remains the concrete compatibility of dependencies and operational tools.

I would choose Deno when its permissions and development model provide concrete value, not simply because it is different. And before migrating a large platform, I would test the components that are most expensive to replace: drivers, SDKs, native modules, observability, and deploys.

In this series

  1. Node.js: why it is still a solid bet
  2. Bun: is it really faster than Node.js?
  3. Deno (this post)
  4. Final comparison: Node.js vs Bun vs Deno

Related reading

References

Performance figures are attributed to the projects that publish them. Deno 2.9 improvements compare Deno versions to each other; they are not an independent ranking of all runtimes. For a production decision, reproduce the scenarios with the same load and publish the versions and configuration.