Deno
Audited from github.com/denoland/deno
Deno is a Rust-based runtime for JavaScript, TypeScript, and WebAssembly that embeds the V8 engine on Tokio, ships secure-by-default permissions, and bundles Deno.Kv, the Cache API, and npm compatibility into one binary.
- Language
- Rust
- Database
- SQLite
- License
- MIT
- Running for
- 6 years
- Team
- 20+ people
Why this architecture
A single Cargo workspace embeds V8 directly in Rust so the CLI, its Web API extensions, and npm compatibility ship as one statically-linked binary instead of relying on a separate Node.js toolchain.
Tech stack by layer
5 technologies · audited Sep 17, 2026- RustImplements the CLI, module graph resolution, permissions model, and every extension crate in the Cargo workspace.
- V8Default JavaScript and WebAssembly engine, embedded through the deno_v8 facade crate and exposed as the workspace v8 dependency.
- TokioAsync runtime driving the CLI and runtime crates network, filesystem, and subprocess I/O.
- TypeScriptImplements the CLI-facing bootstrap and runtime JS/TS layer that gets precompiled into the V8 snapshot.
- SQLiteBacks Deno.Cache and local Deno.Kv storage via the bundled denokv_sqlite and rusqlite crates.
- GitHub ActionsRuns CI, ecosystem/node-compat test suites, and the cargo/npm publish and release-tagging pipelines.
Deno architecture diagram
Open SVGDiagram as text
- JS / TS program (deno run · deno test) → deno CLI (cli/ · module graph · perms): deno run
- deno CLI (cli/ · module graph · perms) → runtime crate (runtime/ · Tokio): boot
- deno CLI (cli/ · module graph · perms) → libs/npm* crates (npm resolver · installer): npm: specifiers
- runtime crate (runtime/ · Tokio) → ext/* crates (fetch · crypto · kv · node): Web APIs
- runtime crate (runtime/ · Tokio) → deno_core (V8 default · QuickJS opt-in): execute JS
- deno_core (V8 default · QuickJS opt-in) → V8 startup snapshot (runtime/js · cli/js): load at start
- ext/* crates (fetch · crypto · kv · node) → SQLite (denokv_sqlite) (Deno.Kv · Cache API): Deno.Kv · caches
- libs/npm* crates (npm resolver · installer) → npm registry (packages): fetch
- deno CLI (cli/ · module graph · perms) → Desktop apps (libdenort (cdylib)): C-ABI runtime
Key architectural decisions
6 decisions- 01
One Cargo workspace splits the CLI from ~70 extension and lib crates
Cargo.toml lists cli, runtime, every ext/* Web API implementation (fetch, crypto, kv, webgpu, node, …) and every libs/* helper (npm, node_resolver, lockfile, eszip) as separate workspace members with independently versioned deno_* crates, so an extension can be compiled, tested, and released without touching the CLI binary.
- 02
V8 is the default engine but QuickJS is a feature-gated alternative
cli/Cargo.toml defines a default v8 feature (deno_core/v8, v8/v8) alongside an opt-in quickjs feature (deno_core/quickjs, v8/quickjs), letting the same deno_core abstraction target either JS engine without a source-level fork of the CLI.
- 03
Deno.Kv and the Cache API share one bundled SQLite backend
The workspace pulls in denokv_sqlite with default features disabled to avoid a second bundled SQLite, and ext/kv plus ext/cache implement the Deno.Kv and Cache Web API surfaces on top of it, so both features ship without an external database dependency.
- 04
The runtime JS layer is precompiled into a V8 snapshot at build time
runtime/snapshot.rs and the cli/snapshot crate (deno_snapshots) build a startup snapshot from runtime/js and cli/js during compilation; an hmr feature flag disables snapshotting so the JS sources are loaded from disk instead, for faster local iteration on the runtime layer.
- 05
npm compatibility is isolated into dedicated resolver and installer crates
libs/npm, libs/npm_cache, libs/npm_installer, libs/npmrc, and libs/node_resolver implement npm registry resolution, the global npm cache, and Node-style module resolution as standalone crates consumed by cli/lib, keeping Node/npm compatibility logic out of the core module graph code.
- 06
Desktop embedding gets its own C-ABI runtime crate
cli/rt_desktop/Cargo.toml builds denort_desktop as a cdylib (crate-type cdylib) depending on the laufey crate, producing a libdenort shared library that desktop apps can embed, separate from the denort executable built by cli/rt.
How Deno is built
How Deno is structured
Deno is a Cargo workspace, not a single crate: the root Cargo.toml lists the cli binary crate, the runtime library crate, roughly two dozen ext/* crates that each implement one Web API (ext/fetch, ext/crypto, ext/kv, ext/webgpu, ext/node, …), and a dozen libs/* crates that provide shared infrastructure (libs/npm, libs/node_resolver, libs/lockfile, libs/eszip, libs/config). Each extension is versioned and published as its own deno_* crate, so the CLI binary is really an assembly of many independently testable pieces rather than one monolith. doc/architecture.md and doc/codebase-map.md in the repository describe this layout for contributors.
Backend & APIs
The cli crate (cli/Cargo.toml, package name deno) is the entry point: it owns argument parsing, the module graph and type-checker (cli/graph_util.rs, cli/type_checker.rs), the language server (cli/lsp), and the deno task shell runner (cli/task_runner.rs). It depends on deno_runtime (the runtime/ crate), which wires the V8 isolate to the ext/* extensions and exposes the actual Deno.* global APIs implemented in runtime/js. JavaScript execution goes through deno_core, Deno's own embedding layer over V8; the workspace pins v8 = { package = "deno_v8", path = "./libs/deno_v8" } in cli/Cargo.toml, and the CLI's v8 feature wires deno_core/v8 and v8/v8 together. A separate denort binary (cli/rt/Cargo.toml) provides the minimal runtime used by deno compile output, and cli/rt_desktop builds a cdylib (denort_desktop) that exposes the runtime as a shared library for embedding in desktop apps, per doc/desktop-architecture.md.
Networking, filesystem access, subprocess handling, and the async executor all run on Tokio, declared as a workspace dependency in runtime/Cargo.toml and cli/Cargo.toml. HTTP fetch (ext/fetch) layers hyper, rustls, and h2 on top of Tokio; the FFI extension (ext/ffi) uses cranelift for JIT trampolines into native libraries.
Data & persistence
ext/kv/Cargo.toml implements Deno.Kv, and ext/cache/Cargo.toml implements the Cache Web API; both ultimately store data through SQLite. The root Cargo.toml pins denokv_sqlite with default features disabled ("brings in bundled sqlite if we don't disable the default features") alongside denokv_proto and denokv_remote, and ext/cache/Cargo.toml depends directly on rusqlite. This means both KV and Cache work offline out of the box with no external database process — the SQLite files live under Deno's local cache directory (managed by the deno_cache_dir crate, libs/cache_dir).
Build, test & deploy
The JS/TS side of the runtime (runtime/js, cli/js) is compiled and embedded into the binary as a V8 startup snapshot at build time, implemented in runtime/snapshot.rs and the deno_snapshots crate (cli/snapshot/Cargo.toml); an hmr Cargo feature disables the snapshot step in favor of loading JS from disk for faster local rebuilds. Linting and formatting are handled by Deno's own dprint-based tooling (tools/lint.js, tools/format.js, .dprint.json), and tools/x.ts plus the scripts under tools/ drive release cutting (tools/cut_a_release.md, tools/release). CI, defined under .github/workflows as generated YAML files (ci.generated.yml, ecosystem_compat_test.generated.yml, node_compat_test.generated.yml), runs the Rust and JS test suites (tests/unit, tests/unit_node, tests/specs, tests/wpt for Web Platform Tests) plus the npm and cargo publish workflows (npm_publish.generated.yml, cargo_publish.generated.yml).
What to copy (and what not to)
The extension-per-crate pattern (ext/*, each with its own Cargo.toml, version, and README) is a reusable idea for any Rust project embedding a scripting engine: it keeps unrelated Web APIs (WebGPU, FFI, crypto) independently compilable and testable, and lets contributors work on one API surface without rebuilding the whole runtime. The npm/Node compatibility layer split across libs/npm* and libs/node_resolver is also a useful reference for teams building a second, compatible module-resolution system alongside a primary one. What is specific to Deno's scale and V8 integration — hand-rolled JIT trampolines in ext/ffi, the dual V8/QuickJS engine abstraction in deno_core, and the custom snapshot build step — is not something most application teams need to replicate; it exists because Deno is building a language runtime, not a typical web service.
Sources & repo audit
- Workspace Cargo.toml (crate layout, pinned deno_* versions)
- cli/Cargo.toml (CLI binary, v8/quickjs feature flags)
- runtime/Cargo.toml (deno_runtime crate dependencies)
- cli/rt_desktop/Cargo.toml (denort_desktop cdylib)
- doc/architecture.md
Independent analysis of repository at github.com/denoland/deno. Spotted an inaccuracy? Use the claim form to request a correction.
Show this stack on your README or website
[](https://stackitfast.com/project/deno)Paste it into your README. It shows your current stack and links to this page.
Scaffold it with your agent
Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Deno's architecture.
- 1Copy the promptThe full markdown spec, with every layer and decision.
- 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
- 3Paste and scaffoldUse it as the first instruction; review before you ship.
# MISSION: Scaffold "Deno" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Deno**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Deno
- **What It Does**: Deno is a Rust-based runtime for JavaScript, TypeScript, and WebAssembly that embeds the V8 engine on Tokio, ships secure-by-default permissions, and bundles Deno.Kv, the Cache API, and npm compatibility into one binary.
- **Domain & Category**: Secure JavaScript & TypeScript Runtime
- **Production Scale**: 20+ people
- **Development Mode**: CLASSIC
- **Architectural Rationale**: A single Cargo workspace embeds V8 directly in Rust so the CLI, its Web API extensions, and npm compatibility ship as one statically-linked binary instead of relying on a separate Node.js toolchain.
- **Live Website Reference**: https://deno.com
- **Source Repository**: https://github.com/denoland/deno
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Rust, TypeScript, V8, Tokio, SQLite
- **Primary Language(s)**: Rust, TypeScript, JavaScript
- **License of the reference repo**: MIT
- **Backend & APIs**: Rust — Implements the CLI, module graph resolution, permissions model, and every extension crate in the Cargo workspace.; V8 — Default JavaScript and WebAssembly engine, embedded through the deno_v8 facade crate and exposed as the workspace v8 dependency.; Tokio — Async runtime driving the CLI and runtime crates network, filesystem, and subprocess I/O.; TypeScript — Implements the CLI-facing bootstrap and runtime JS/TS layer that gets precompiled into the V8 snapshot.
- **Data & persistence**: SQLite — Backs Deno.Cache and local Deno.Kv storage via the bundled denokv_sqlite and rusqlite crates.
- **Infrastructure & deploy**: GitHub Actions — Runs CI, ecosystem/node-compat test suites, and the cargo/npm publish and release-tagging pipelines.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/denoland/deno @ abd2207)
1. **One Cargo workspace splits the CLI from ~70 extension and lib crates**: Cargo.toml lists cli, runtime, every ext/* Web API implementation (fetch, crypto, kv, webgpu, node, …) and every libs/* helper (npm, node_resolver, lockfile, eszip) as separate workspace members with independently versioned deno_* crates, so an extension can be compiled, tested, and released without touching the CLI binary.
2. **V8 is the default engine but QuickJS is a feature-gated alternative**: cli/Cargo.toml defines a default v8 feature (deno_core/v8, v8/v8) alongside an opt-in quickjs feature (deno_core/quickjs, v8/quickjs), letting the same deno_core abstraction target either JS engine without a source-level fork of the CLI.
3. **Deno.Kv and the Cache API share one bundled SQLite backend**: The workspace pulls in denokv_sqlite with default features disabled to avoid a second bundled SQLite, and ext/kv plus ext/cache implement the Deno.Kv and Cache Web API surfaces on top of it, so both features ship without an external database dependency.
4. **The runtime JS layer is precompiled into a V8 snapshot at build time**: runtime/snapshot.rs and the cli/snapshot crate (deno_snapshots) build a startup snapshot from runtime/js and cli/js during compilation; an hmr feature flag disables snapshotting so the JS sources are loaded from disk instead, for faster local iteration on the runtime layer.
5. **npm compatibility is isolated into dedicated resolver and installer crates**: libs/npm, libs/npm_cache, libs/npm_installer, libs/npmrc, and libs/node_resolver implement npm registry resolution, the global npm cache, and Node-style module resolution as standalone crates consumed by cli/lib, keeping Node/npm compatibility logic out of the core module graph code.
6. **Desktop embedding gets its own C-ABI runtime crate**: cli/rt_desktop/Cargo.toml builds denort_desktop as a cdylib (crate-type cdylib) depending on the laufey crate, producing a libdenort shared library that desktop apps can embed, separate from the denort executable built by cli/rt.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
- Structure as a Turborepo monorepo with strict package boundaries:
- `apps/web`: Application UI, routing, layouts, and server endpoints.
- `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
- `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
- `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
- Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
- Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
- Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
- Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
- Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
- Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
- Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (SQLite): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.Frequently asked about Deno
What is Deno built with?
Deno is written in Rust on top of the Tokio async runtime, embeds the V8 JavaScript engine through the deno_v8 crate, and ships a TypeScript/JavaScript bootstrap layer that is precompiled into a V8 snapshot at build time.
Does Deno depend on Node.js to run?
No. Deno is a single statically-linked Rust binary; its npm compatibility layer (libs/npm, libs/node_resolver) reimplements Node module resolution rather than shelling out to a Node.js install.
What database does Deno.Kv use?
Deno.Kv and the Cache Web API are backed by a bundled SQLite engine via the denokv_sqlite and rusqlite crates declared in the workspace Cargo.toml, so no external database server is required.
Can Deno run without V8?
The cli/Cargo.toml build defines an opt-in quickjs feature that swaps the default V8 engine for QuickJS through the same deno_core abstraction, though V8 remains the default and most widely used engine.
One email a month: new deep dives and stack trends
New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.
Similar architectures
- BunClassicAll-in-One JavaScript Runtime & Toolchain · 1M+ MAUShares Rust · TypeScript · SQLite
- UplevelerHybridDeveloper Work Log & Promotion Coach · SoloShares Rust · Tokio
- Actix WebClassicRust Web Framework · 1M+ MAUShares Rust · Tokio
- AxumClassicRust Web Framework · 1M+ MAUShares Rust · Tokio
- DioxusClassicCross-Platform Rust App Framework · 6-20 peopleShares Rust · Tokio
- VaultwardenClassicLightweight Self-Hosted Password Vault · Solo / 2-5 peopleShares Rust · SQLite · Tokio