JavaScript/TypeScript Runtimes (Deno, Bun, Edge) & WinterTC Interop
Parent: JavaScript and Node.js · researched 2026-06-01T01:50:16.157Z· 17 sources · 5 concepts · skill javascript-runtimes-deno-bun-edge
PROVENANCE: Authored by /dr (deep-research-and-build) on 2026-05-31.
Overview
- PROVENANCE: Authored by /dr (deep-research-and-build) on 2026-05-31. [source]
- HUB: programming-languages (reference spoke). NOT a standalone top-level skill. [source]
- SCOPE: Alternative/non-Node JS-TS runtimes (Deno 2.x, Bun 1.x) + edge runtimes + the [source]
- WinterTC/WinterCG cross-runtime interop standard. Cross-references the sibling [source]
- javascript-nodejs and nodejs-concurrency-internals references for Node-specific depth. [source]
- SOURCES: WinterTC ECMA-429 (min-common-api.proposal.wintertc.org), W3C WinterCG→WinterTC [source]
- transition, Deno 2 blog/docs (deno.com, docs.deno.com), Bun 1.2/1.3 blog+docs (bun.com), [source]
- Cloudflare Workers nodejs_compat docs+blog, Vercel Edge Runtime, Deno Deploy docs. [source]
JavaScript/TypeScript Runtimes: Deno 2.x, Bun 1.x, Edge Runtimes & WinterTC Interop
- A programming-languages hub reference covering the non-Node JS/TS runtime landscape and the [source]
- cross-runtime interop standard that ties them together. For Node.js language/runtime APIs and [source]
- event-loop internals, defer to the sibling references javascript-nodejs.md and [source]
- nodejs-concurrency-internals.md - this file assumes that foundation and focuses on what differs. [source]
Overview
- There are now four practically-relevant server-side JS/TS execution targets: [source]
- The unifying thread is WinterTC (formerly WinterCG): the standard defining the **Minimum Common [source]
- Web Platform API** - the subset of browser/Web APIs every server runtime implements identically, so [source]
- code written to that surface is portable across all of them. Understand WinterTC first; it is the [source]
- shared branch every runtime below inherits from. [source]
Core Concept 1 — WinterTC / WinterCG & the Minimum Common Web Platform API (the shared foundation)
- History. WinterCG (Web-interoperable Runtimes Community Group, a W3C CG founded by Cloudflare, [source]
- Vercel, Deno, Shopify and others) incubated a "minimum common API." In January 2025 WinterCG was [source]
- wound down and the work moved to Ecma TC55 ("WinterTC" - Technical Committee on Web-interoperable [source]
- Server Runtimes). The spec is now ECMA-429 ("Minimum common web API"), adopted by the Ecma [source]
- General Assembly in December 2025, with yearly snapshots. [source]
- What's in the Minimum Common Web Platform API (the portable surface): [source]
- Fetch & data: fetch(), Headers, Request, Response, Blob, File, FormData [source]
- Streams: ReadableStream, WritableStream, TransformStream + controllers; CompressionStream/DecompressionStream [source]
- Encoding/text: TextEncoder/TextDecoder (+ stream variants), atob/btoa [source]
- Crypto: crypto (Crypto, CryptoKey, SubtleCrypto) - Web Crypto, not Node crypto [source]
- URL: URL, URLSearchParams, URLPattern [source]
- Events/messaging: Event, EventTarget, CustomEvent, AbortController/AbortSignal, MessageChannel/MessagePort, MessageEvent [source]
- Timers: setTimeout/setInterval/clear*, queueMicrotask, performance [source]
- Utilities: structuredClone, console, navigator.userAgent, reportError [source]
- WebAssembly: WebAssembly.* [source]
- Global handlers: onerror, onunhandledrejection, onrejectionhandled [source]
- Explicitly NOT required: Web Workers, the DOM (window, document), and HTML element [source]
- interfaces. (WinterTC plans future conformance levels - e.g. CLI/File-Systems, Graphics, Servers [source]
- with advanced networking - layered above the minimum.) [source]
- Runtime Keys (separate WinterTC registry): standardized identifiers for runtimes used in [source]
- package.json exports conditions, engines, and runtime detection. Common keys: node, deno, [source]
- bun, workerd, edge-light, electron, fastly, netlify, react-native, react-server. [source]
- Keys are immutable once approved and require "proof of use." Use them to ship runtime-specific entry [source]
- > Practical rule: write to the Minimum Common API by default; only branch on a Runtime Key when [source]
- > you genuinely need a runtime-specific capability. Branching is the exception, portability the rule. [source]
Core Concept 2 — Deno 2.x
- Deno 2.0 shipped October 2024 (four years after 1.0); the line is now considered stable and [source]
- production-ready, with a Long-Term Support (LTS) channel. [source]
- Headline of 2.x = Node/npm backwards compatibility (the thing that blocked adoption in 1.x): [source]
- Understands package.json, node_modules/, and npm workspaces - run Deno inside existing [source]
- npm: specifiers (import express from "npm:express@4") and node: builtins [source]
- (import { createServer } from "node:http"). [source]
- Package-management subcommands: deno install, deno add, deno remove (so deno doubles as a [source]
- package manager). deno install is reported ~15% faster than npm cold-cache, ~90% faster hot-cache. [source]
- nodeModulesDir: "auto" | "manual" in deno.json (or --node-modules-dir=auto|manual) controls [source]
- whether a real node_modules/ is materialized. [source]
- Defining Deno traits (still true in 2.x): [source]
- Secure by default - no file/network/env access unless granted: --allow-net, --allow-read, [source]
- --allow-env, or --allow-all/-A. This is the biggest behavioral difference from Node/Bun. [source]
- (Node has since added an opt-in parallel - the stable 24.x Permission Model, node --permission [source]
- + --allow-fs-read/--allow-net/etc.; see the sibling reference nodejs-typescript-and-runtime-features.md. [source]
- Deno's is the inverse default: deny-by-default vs Node's allow-by-default.) [source]
- TypeScript with zero config - run .ts directly, no tsconfig/transpile step required. [source]
- Web-standard first - fetch, Web Crypto, streams are globals (WinterTC alignment). [source]
- Built-in toolchain - deno fmt, deno lint, deno test, deno bench, deno compile [source]
- (single-file executables), deno task (script runner). [source]
- Config: deno.json/deno.jsonc - imports map, tasks, lint/fmt config, compiler options. [source]
- JSR (jsr: / jsr.io) - Deno's TypeScript-first registry; publishes TS source, generates docs, [source]
- works across runtimes (also installable from npm). [source]
- Deno KV - built-in key-value store (Deno.openKv()); on Deno Deploy it's globally distributed [source]
- on FoundationDB. Available in Node via the @deno/kv npm package (SQLite-backed locally). [source]
- Deno Queues - kv.enqueue() / kv.listenQueue(), at-least-once delivery. [source]
Core Concept 3 — Bun 1.x (runtime + package manager + test + bundler)
- Bun is an all-in-one toolkit written in Zig, powered by JavaScriptCore (not V8) - the [source]
- JSC choice drives its fast startup and low memory. Positioned as a drop-in Node.js replacement. [source]
- Node compatibility: since 1.2, Bun runs the Node.js test suite on every commit; many core [source]
- modules (node:http, node:http2, node:dgram, node:cluster, node:zlib, etc.) pass >90% of [source]
- their tests. Bun also implemented V8 C++ APIs inside JSC so native N-API addons (e.g. cpu-features) [source]
- As a package manager (bun install) - works in any package.json project: [source]
- Up to ~25x faster than npm; supports workspaces (reads the workspaces key, single-pass install, [source]
- de-dup), git/http/tarball deps, custom registries, .npmrc. [source]
- bun.lock - text-based JSONC lockfile (default since 1.2, replacing binary bun.lockb); [source]
- reviewable in PRs, mergeable. Migrate with [source]
- bun install --save-text-lockfile --frozen-lockfile --lockfile-only then delete bun.lockb. [source]
- Isolated installs (1.3): central store in node_modules/.bun/ with symlinks → packages only see [source]
- declared deps (kills phantom deps). Default linker: isolated for new monorepos, hoisted for new [source]
- single packages and pre-existing projects (backward compat). [source]
- Commands: bun add/remove/update, bun outdated, bun publish, bun patch, bun run --filter. [source]
- **Built-in runtime APIs (the Bun.* namespace + bun: modules):** [source]
- Bun.serve() - HTTP/WebSocket server with static routes (~40% faster than dynamic handlers); [source]
- Express runs ~3x faster on Bun than Node. [source]
- bun:sqlite - native SQLite (query.as(Class) for ORM-less mapping). [source]
- Bun.sql - native PostgreSQL client, tagged-template parameterized queries, pooling (~50% faster [source]
- than popular Node Postgres libs); also Bun.redis. [source]
- Bun.s3 - built-in S3 client (~5x faster downloads than @aws-sdk/client-s3), presigned URLs, [source]
- multipart writer(), integrates with fetch()/Bun.serve(). [source]
- Bun.file() (.delete(), .stat(), S3-backed), Bun.udpSocket(), Bun.color(). [source]
- Test runner (bun test): Jest-compatible expect, JUnit XML + LCOV for CI, inline snapshots [source]
- (toMatchInlineSnapshot()), test.only() w/o flags. [source]
- Bundler/build: HTML imports, built-in CSS parser (LightningCSS-derived), bytecode caching (~2x [source]
- faster startup), cross-compilation (build Windows/macOS binaries on Linux), bun build --compile. [source]
Core Concept 4 — Edge Runtimes (workerd / Vercel Edge / Deno Deploy)
- Edge runtimes run JS in V8 isolates (lightweight contexts, not containers) distributed across [source]
- global POPs - sub-millisecond cold starts, no per-request VM boot. The execution model is a [source]
- handler: Request → Response. They expose the WinterTC Minimum Common API, not full Node. [source]
- Hard constraints to design around: [source]
- Stateless - no durable in-memory state between requests; persistence needs external stores [source]
- (KV, D1, Durable Objects, databases-over-HTTP). [source]
- Tight CPU/memory budgets - e.g. memory commonly capped ~128 MB, CPU time tens of ms (provider- [source]
- and plan-specific; Cloudflare offers higher CPU limits on paid tiers). [source]
- No raw filesystem / no long-running event loop / no Node net server by default. [source]
- TCP/raw-socket and many npm packages that assume Node internals won't work unless a compat shim is on. [source]
- Cloudflare Workers (workerd) - V8 isolates, 330+ POPs. nodejs_compat is an umbrella [source]
- compatibility flag enabling Node APIs incrementally (granular sub-flags exist). Unsupported APIs are [source]
- polyfilled by Wrangler via unenv when nodejs_compat is on and the compatibility date is [source]
- ≥ 2024-09-23. 2025 added real implementations gated by compat date: node:net/node:dns/ [source]
- node:timers (Jan 2025), node:fs + Web FS (enable_nodejs_fs_module, auto ≥ 2025-09-15), [source]
- node:os (≥ 2025-09-15), node:console (≥ 2025-09-21), node:vm stub (≥ 2025-10-01). [source]
- Storage/compute primitives: KV, R2, D1, Durable Objects, Queues, Cron Triggers. [source]
- Vercel Edge Functions / Edge Runtime - V8 + a subset of Node APIs ("Edge Runtime"), [source]
- WinterCG/WinterTC-compliant; open-source edge-runtime package emulates it locally. Fast cold [source]
- starts; many npm packages work if they stick to the Web-standard subset. [source]
- Deno Deploy - multi-tenant V8 isolate cloud; TS-first, native ESM, no bundler step. Now [source]
- supports npm: specifiers and node: builtins (run existing Node apps like node:http at the [source]
- edge). Primitives: Deno KV (FoundationDB-backed, globally replicated), Deno Queues. [source]
- Subhosting = run your users' untrusted code securely in isolates (multi-tenant PaaS). Dec 2025: [source]
- detects Deno/npm workspace/monorepo configs to deploy from subdirectories. (Note the [source]
- "Deploy Classic" → new Deno Deploy migration path.) [source]
- Compatibility-date discipline (Cloudflare): the compatibility_date (+ optional [source]
- compatibility_flags) pins runtime behavior. Bumping the date can flip on new Node modules or change [source]
- defaults - treat it as a deliberate, tested upgrade, not a passive value. [source]
Core Concept 5 — Choosing & migrating between runtimes
- Maximum ecosystem certainty / existing large app → Node.js (the baseline; see javascript-nodejs.md). [source]
- TS-first, security sandboxing, batteries-included tooling, JSR → Deno 2.x. [source]
- Raw speed + single-tool DX (install/run/test/bundle), heavy local I/O (SQLite/Postgres/S3) → Bun 1.x. [source]
- Global low-latency, request/response, sub-ms cold start, no servers to manage → Edge. [source]
- Portability strategy (works everywhere): [source]
- Code to the Minimum Common Web Platform API (fetch/streams/Web Crypto/URL/TextEncoder). [source]
- Prefer ESM; use package.json exports with Runtime Keys only for genuine per-runtime branches. [source]
- Keep Node-specific built-ins (fs, net, native addons) behind an abstraction so edge targets can [source]
- swap them for a Web-standard or platform primitive. [source]
- Verify with each runtime's compat tracking (Bun's Node test-suite pass rate; Cloudflare's [source]
- nodejs_compat + compat-date matrix; Deno's node:/npm: support). [source]
Practical Patterns
- One server, three runtimes: a handler exporting default { fetch(req) { return new Response(...) } } [source]
- is the portable shape - it runs on Deno (Deno.serve), Bun (Bun.serve/default export), and edge [source]
- (workerd/Vercel) with minimal glue. [source]
- Deno running a Node app: add package.json, set nodeModulesDir: "auto" in deno.json, use [source]
- deno install then deno run -A npm:... - no rewrite needed for ESM projects. [source]
- Bun as a faster CI package manager only: drop bun install into a Node project (commit [source]
- bun.lock), keep running the app on Node - Bun-as-pm is decoupled from Bun-as-runtime. [source]
- Edge + state: never hold state in module scope expecting persistence; route durable state to KV/ [source]
- D1/Durable Objects (Cloudflare) or Deno KV/Queues (Deno Deploy). [source]
Anti-Patterns
- Assuming "Node-compatible" = 100%. Bun ~90%+ on supported modules; Cloudflare's coverage is [source]
- gated by compat date/flags; Deno supports node:/npm: but not every native edge case. Test, don't assume. [source]
- Using Node crypto/Buffer/fs in edge code that targets the Web-standard subset - reach for [source]
- Web Crypto (crypto.subtle), Uint8Array/Blob, and platform storage instead. [source]
- Leaving Cloudflare compatibility_date stale (or bumping it blind). Stale = you miss fixes/new [source]
- modules; blind bump = behavior changes silently. Pin and upgrade deliberately. [source]
- Committing bun.lockb (binary) in 2025+. Migrate to text bun.lock for reviewable diffs. [source]
- Relying on phantom dependencies under Bun's hoisted linker - use isolated installs in monorepos. [source]
- Shipping a Deno script that silently needs broad perms - scope --allow-* tightly; -A defeats [source]
Troubleshooting
- npm package fails on edge → it likely imports a Node built-in; enable nodejs_compat + check [source]
- compat date (Cloudflare), or refactor to the Web-standard subset. [source]
- Deno "Requires net access" / permission error → add the matching --allow-net/--allow-read flag. [source]
- Bun behaves differently from Node on a module → check Bun's Node compatibility tracker for that [source]
- node: module's pass rate; file/upstream if it's a gap. [source]
- Cold start still slow on "edge" → confirm you're on an isolate runtime (workerd/V8 isolates), not a [source]
- container-backed serverless function masquerading as edge. [source]
- Lockfile merge conflicts in Bun → you're on binary bun.lockb; migrate to text bun.lock. [source]
References
- WinterTC Minimum Common Web Platform API (ECMA-429): https://min-common-api.proposal.wintertc.org/ [source]
- WinterTC FAQ / TC55: https://wintertc.org/faq [source]
- W3C: Goodbye WinterCG, welcome WinterTC (Jan 2025): https://www.w3.org/community/wintercg/2025/01/10/goodbye-wintercg-welcome-wintertc/ [source]
- WinterTC Runtime Keys proposal: https://runtime-keys.proposal.wintercg.org/ [source]
- Announcing Deno 2: https://deno.com/blog/v2.0 [source]
- Deno Node & npm compatibility docs: https://docs.deno.com/runtime/fundamentals/node/ [source]
- Native npm support on Deno Deploy: https://deno.com/blog/npm-on-deno-deploy [source]
- Deno KV via npm: https://deno.com/blog/kv-npm [source]
- Bun (GitHub): https://github.com/oven-sh/bun [source]
- Bun 1.2 release: https://bun.com/blog/bun-v1.2 [source]
- Bun text lockfile: https://bun.com/blog/bun-lock-text-lockfile [source]
- Bun package manager / install docs: https://bun.com/docs/pm/cli/install [source]
- Cloudflare Workers Node.js compatibility: https://developers.cloudflare.com/workers/runtime-apis/nodejs/ [source]
- Cloudflare compatibility flags: https://developers.cloudflare.com/workers/configuration/compatibility-flags/ [source]
- A year of Node.js compat in Workers (2025): https://blog.cloudflare.com/nodejs-workers-2025/ [source]
- Vercel Edge Runtime: https://edge-runtime.vercel.app/ [source]
Children
- WinterTC / WinterCG Minimum Common Web Platform API (ECMA-429) + Runtime Keys (frontier)
- Deno 2.x runtime (Node/npm compat, npm:/node: specifiers, deno.json, JSR, Deno KV/Queues, secure-by-default perms, LTS) (frontier)
- Bun 1.x runtime + package manager (JavaScriptCore, bun install, text bun.lock, isolated installs, Bun.serve/bun:sqlite/Bun.sql/Bun.s3, bun test, bundler) (frontier)
- Edge runtimes (Cloudflare Workers/workerd nodejs_compat + compatibility dates + unenv, Vercel Edge Runtime, Deno Deploy isolates/subhosting) (frontier)
- Choosing & migrating between Node/Deno/Bun/edge (portability via Minimum Common API + Runtime-Key exports) (frontier)
Frontier under this node: Bun 1.x runtime + package manager (JavaScriptCore, bun install, text bun.lock, isolated installs, Bun.serve/bun:sqlite/Bun.sql/Bun.s3, bun test, bundler), Choosing & migrating between Node/Deno/Bun/edge (portability via Minimum Common API + Runtime-Key exports), Deno 2.x runtime (Node/npm compat, npm:/node: specifiers, deno.json, JSR, Deno KV/Queues, secure-by-default perms, LTS), Edge runtimes (Cloudflare Workers/workerd nodejs_compat + compatibility dates + unenv, Vercel Edge Runtime, Deno Deploy isolates/subhosting), WinterTC / WinterCG Minimum Common Web Platform API (ECMA-429) + Runtime Keys