Open-Source Wikis

/

Deno

/

Lore

denoland/deno

Lore

The story of how the Deno codebase got to where it is. Dates are derived from git tags and commit history; "the why" is sometimes inferred from commit messages and PRs and is hedged accordingly.

Eras

The Go-prototype era (May–Jul 2018)

The project's first commit landed in May 2018. The original prototype was written in Go, with V8 driving JavaScript execution and Go orchestrating the runtime. Within weeks the team realized Go's GC model conflicted with V8's expectations and started a rewrite.

Key events:

  • May 2018 — repository created, first runtime experiments
  • Jul 2018 — first public talk by Ryan Dahl introducing Deno

The Rust rewrite (Aug 2018 – May 2020)

Over the next ~22 months Deno was rewritten in Rust. This is when most of the architecture you see today crystallized: the JsRuntime ↔ V8 binding (eventually pulled out into deno_core), the op boundary, the snapshot machinery, the Tokio integration, and the permission system. By the time v1.0 shipped on 2020-05-14, Deno had its core shape — runtime + extensions + permissioned ops + secure-by-default — that survives essentially intact today.

Steady runtime build-out (May 2020 – Q4 2022)

Once the v1.0 line was out the door the team filled in the web platform: streams, fetch, WebSocket, WebCrypto, WebGPU, BroadcastChannel, KV (initially as an unstable API), and the LSP. The ext/ directory grew from a handful of folders to its current 30+. The CI moved from Cirrus to GitHub Actions in this period, and the workflow files in .github/workflows/ got the now-canonical "generated from .ts source" pattern (*.ts + *.generated.yml).

Node compatibility push (~2022 – 2024)

Originally Deno positioned itself in opposition to Node's module system. Around late 2022 the project flipped: the npm: specifier landed, the node: specifier became first class, and ext/node (with its sub-crates ext/node_crypto, ext/node_sqlite) grew into one of the largest extensions in the repo. The tests/node_compat/ suite tracks how much of Node's own test suite Deno can pass.

Notable milestones in this era:

  • npm: specifier — added as unstable, then stabilized
  • node_modules/ support — including BYONM mode ("nodeModulesDir": "manual" in deno.json)
  • package.json supportlibs/package_json reads it, libs/node_resolver honors exports/imports
  • deno_core published independentlylibs/core became reusable outside the Deno binary

v2.0 and the JSR era (Q3 2024 – present)

v2.0 shipped on 2024-10-08. The release consolidated the npm/Node story (deno install, deno add, deno remove, etc., became first-class), introduced the JSR registry as a peer to npm, and stabilized many "unstable" features. Subsequent v2.x releases focused on:

  • JSR maturationjsr: specifiers, JSR publishing, deno publish
  • TypeScript performance — adoption of tsgo (TypeScript written in Go) communicated over IPC via libs/typescript_go_client
  • deno compile improvements — better cross-platform compilation, smaller binaries
  • Workspace ergonomicslibs/config/workspace/mod.rs has grown to 6,815 lines as workspace support has deepened
  • Dev toolsdeno bump-version (added 2026-04-29), deno outdated, install --prod/--os/--arch flags

The current branch line is v2.7.x (v2.7.0 tagged 2026-02-25, v2.7.14 is the most recent at snapshot).

Longest-standing features

These are pieces of the codebase that have survived multiple major rewrites and are still core today.

Subsystem First introduced Current location Notes
Permission gating v0.x (2018) runtime/permissions/lib.rs Largest single source file in the repo at 10,921 lines; the permission categories have stayed remarkably stable since v1.0
op_* boundary v0.x (2018), refactored to op2 ~2023 libs/ops, callers in every ext/*/lib.rs The original op macro has been replaced by op2 but the design (typed Rust function, JS-callable) is intact
Snapshots v0.x cli/snapshot/, runtime/snapshot.rs Critical for startup time
tsc integration v0.x cli/tsc.rs, cli/tsc/ Originally always-on, now opt-in (--check); tsgo is the modern alternative
LSP ~2020 cli/lsp/ Has grown from a thin shim to ~1.1MB of source over six years
Spec test format early 2020 tests/specs/__test__.jsonc schema in tests/specs/schema.json The wildcard matcher ([WILDCARD], [WILDLINE], [UNORDERED_*]) is unchanged

Major rewrites and migrations

  • Go → Rust (2018) — the original implementation language change.
  • opop2 (~2023) — the macro for binding Rust functions to JS got a redesign that supports better type inference, async, and bigint without manual serialization.
  • Module loader (~2022) — refactor of cli/module_loader.rs to support npm:/jsr: alongside HTTPS imports. The file is now 1,668 lines.
  • tsctsgo (in progress) — TypeScript type checking is being migrated from the bundled JS-based tsc to tsgo (Go-based TypeScript), spoken to over IPC. libs/typescript_go_client is the IPC client.
  • CI generation — the .github/workflows/*.yml files are now generated from sibling .ts scripts (ci.ts, pr.ts, etc.) so workflow logic is type-checked.
  • unstable flags consolidation — many features that started life behind individual --unstable-* flags have either stabilized or been folded into runtime/features (UNSTABLE_FEATURES registry).

Deprecated and removed features

The recent commit log shows continuous pruning of legacy behavior. A non-exhaustive sample:

  • Global Node-style proxies — feat: use Node.js timers by default and remove global proxy (commit 2026-04-25 area).
  • "no-process-global" / "no-node-globals" lint rules — disabled by default rather than removed; previously enforced.
  • Some --unstable-* flags — see cli/args/flags.rs for current vs. deprecated unstable flag handling. PR: "fix: drop config-only unstable features from unstable_args() (#33452)".

When the rationale for a deprecation is unclear from commits the surrounding code, the safest read is "Node-compat parity" — most recent breaking changes have been about aligning behavior with Node where Deno had previously diverged.

Growth trajectory

A back-of-envelope timeline from git history:

  • 2018 — repo created, Go prototype
  • 2019 — Rust runtime taking shape, V8 bindings (later deno_core) maturing
  • May 2020 — v1.0
  • 2020–2022 — web platform fill-in, LSP introduced
  • 2022–2024 — Node compat push, npm: specifier
  • Oct 2024 — v2.0
  • 2025 — JSR maturation, workspace support deepens, tsgo introduced
  • Feb 2026 — v2.7.0
  • Apr 2026 (snapshot) — v2.7.14, deno bump-version and install --prod added in the latest commits

For per-page contributor info, see the active-contributors byline at the top of each domain page.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Lore – Deno wiki | Factory