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 stabilizednode_modules/support — including BYONM mode ("nodeModulesDir": "manual"indeno.json)package.jsonsupport —libs/package_jsonreads it,libs/node_resolverhonorsexports/importsdeno_corepublished independently —libs/corebecame 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 maturation —
jsr:specifiers, JSR publishing,deno publish - TypeScript performance — adoption of
tsgo(TypeScript written in Go) communicated over IPC vialibs/typescript_go_client deno compileimprovements — better cross-platform compilation, smaller binaries- Workspace ergonomics —
libs/config/workspace/mod.rshas grown to 6,815 lines as workspace support has deepened - Dev tools —
deno bump-version(added 2026-04-29),deno outdated, install--prod/--os/--archflags
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.
op→op2(~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.rsto supportnpm:/jsr:alongside HTTPS imports. The file is now 1,668 lines. tsc→tsgo(in progress) — TypeScript type checking is being migrated from the bundled JS-basedtsctotsgo(Go-based TypeScript), spoken to over IPC.libs/typescript_go_clientis the IPC client.- CI generation — the
.github/workflows/*.ymlfiles are now generated from sibling.tsscripts (ci.ts,pr.ts, etc.) so workflow logic is type-checked. unstableflags consolidation — many features that started life behind individual--unstable-*flags have either stabilized or been folded intoruntime/features(UNSTABLE_FEATURESregistry).
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 — seecli/args/flags.rsfor 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,
tsgointroduced - Feb 2026 — v2.7.0
- Apr 2026 (snapshot) — v2.7.14,
deno bump-versionand install--prodadded 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.