Deno

Deno is a JavaScript/TypeScript runtime from Node's original creator, Ryan Dahl — built explicitly to fix what he called his "10 things I regret about Node.js." Its defining feature is security by default: a Deno program can't touch the filesystem, network, or environment unless you grant permission on the command line. Code runs in a sandbox; capabilities are opt-in flags.

Around that core, Deno bets on web standards (fetch, Request/Response, Web Crypto — the browser's APIs on the server), native TypeScript, and a complete built-in toolchain (formatter, linter, test runner, compiler). Since Deno 2 it also runs most of npm — dissolving the ecosystem barrier that limited its early adoption.

TL;DR

Quick Example

A typed HTTP server with the permission model in action:

The security model in one sentence: your dependencies run with your permissions — so Deno makes those permissions small and explicit.

Core Concepts

The Permission Sandbox

Deno's process starts with no ambient authority. Capabilities are granted per run:

Why this matters is the supply chain: the npm-era attacks — a transitive dependency exfiltrating environment secrets or reading SSH keys — are structurally blunted when the process simply cannot open ~/.ssh or phone home to an ungranted host. It's not a complete defense (granted capabilities are granted to all code in the process), but it turns "any of my 800 dependencies can do anything" into an auditable, scoped grant list. The same zero-trust instinct, applied to a runtime.

Web Standards on the Server

Deno's API surface is deliberately the browser's: fetch, Request/Response, URL, WebSocket, Web Crypto, streams, localStorage, workers. Deno.serve takes a (Request) => Response handler — the exact signature of Cloudflare Workers, browser service workers, and the WinterTC server-runtime standard. The payoff is portability: a Hono app written this way runs on Deno, Bun, Cloudflare Workers, and Node with the same code, and your browser knowledge transfers 1:1.

Batteries Included

What Node assembles from devDependencies, Deno ships in the binary:

Zero config files for any of them — one less prettierrc/eslintrc/jest.config per repo. The lock-in risk is correspondingly low: these tools mirror community conventions.

npm Compatibility and JSR

Deno 2 ended the ecosystem isolation:

package.json and node_modules are supported when present, so existing Node projects often run under deno run unchanged — and frameworks like Next.js, Astro, and Vite work. JSR (jsr.io) is the forward-looking half: a TypeScript-first registry where packages publish types and source, docs generate from code, and modules work across Deno, Node, and Bun — designed to fix npm's untyped-tarball legacy.

Deno Deploy and the Edge

Deno's commercial platform runs your code (the same web-standard handlers) on a global edge network with git-push deploys, plus platform primitives — Deno KV (built-in distributed key-value store), cron, and queues. The standards alignment is the strategy: code targeting Request => Response deploys to Deno Deploy, Cloudflare, or a container with minimal change. See Serverless Patterns for the architectural fit.

Deno vs Node vs Bun

The honest positioning: Node remains the default for ecosystem gravity and LTS conservatism; Bun wins on toolchain speed; Deno wins where its security model matters (running less-trusted code, supply-chain-sensitive environments), where standards-portability is a goal, or where the integrated platform (Deploy/KV) fits. Node absorbing both rivals' ideas (permission model, TS support, built-in test runner) is the competition working as intended.

Common Mistakes

-A Everywhere

Running everything with --allow-all keeps Deno's syntax and discards its point. Scope permissions per entry point (encode them in deno task definitions so they're versioned), and treat a dependency that needs broad grants as a review flag.

Treating npm Compat as 100%

Most packages work; the long tail (native addons, deep node: internals, packages doing dynamic-require tricks) doesn't always. Like any runtime migration: run your real test suite before believing it.

Fighting the Standards Grain

Porting Node idioms wholesale (node:http servers, CommonJS habits, __dirname gymnastics) works but forfeits the portability dividend. New Deno code should reach for fetch/Request/Response/URL first — that's the code that runs everywhere.

Confusing Deno KV/Deploy Portability

The runtime is open-source and standards-aligned; Deno KV and Deploy primitives are platform features. Building core logic on KV couples you to the platform (self-hosted KV exists but differs operationally) — a fine trade, made consciously.

FAQ

Is Deno production-ready?

Yes — Deno 2 is mature, companies run it in production (notably on Deploy and for internal tooling), and the LTS release channel addresses enterprise cadence concerns. The adoption question is ecosystem fit and team familiarity, not runtime stability.

Deno or Bun — the modern-runtime tiebreaker?

Different theses: Bun optimizes speed and unified DX (installs, tests, bundling); Deno optimizes security and standards (sandbox, web APIs, JSR). Running third-party or AI-generated code? Deno's sandbox is a genuine differentiator. Chasing CI minutes and one-binary tooling? Bun. Both interop with npm well enough that ecosystem access no longer decides it.

Can I run my existing Node app on Deno?

Often, yes — deno run with package.json support executes many Node projects unchanged, and node: built-ins are implemented. Verify with your test suite; native addons and framework dev-servers are the usual friction points.

What is JSR and should I publish there?

A modern package registry: TypeScript-native, provenance-aware, auto-documented, consumable from Deno and Node/Bun. For new open-source TS libraries, publishing to JSR (optionally alongside npm) is increasingly the forward-compatible move.

What happened to the early Deno's URL imports?

Still supported, but the ecosystem consolidated on JSR and npm specifiers with lockfiles — the practical answer to the versioning/duplication pain of raw URL imports. Deno 2's pragmatism (embracing package.json and npm) is what made it a serious Node alternative.

Related Topics

References