denoland/deno

A modern runtime for JavaScript and TypeScript.

106,520 stars Rust 8 components

Executes JavaScript and TypeScript with secure defaults and native performance

Source code enters through CLI argument parsing which resolves module specifiers and loads configuration. The module loader fetches source code (local files or remote URLs), TypeScript gets transpiled through SWC/TSC, modules are loaded into V8 isolate, and JavaScript execution proceeds with op calls bridging back to Rust implementations for I/O and system operations. Results flow back through the op system to JavaScript and finally to stdout/files.

Under the hood, the system uses 3 feedback loops, 4 data pools, 4 control points to manage its runtime behavior.

A 8-component repository. 4956 files analyzed. Data flows through 6 distinct pipeline stages.

How Data Flows Through the System

Source code enters through CLI argument parsing which resolves module specifiers and loads configuration. The module loader fetches source code (local files or remote URLs), TypeScript gets transpiled through SWC/TSC, modules are loaded into V8 isolate, and JavaScript execution proceeds with op calls bridging back to Rust implementations for I/O and system operations. Results flow back through the op system to JavaScript and finally to stdout/files.

  1. Parse CLI arguments and load configuration — CliArgs::from_flags processes command line arguments, loads deno.json/deno.jsonc configuration files, resolves import maps, and constructs PermissionsContainer with allow/deny rules
  2. Resolve module specifiers — ModuleLoader takes import strings and resolves them to ModuleSpecifier URLs using import maps, package.json resolution for Node compatibility, and JSR/NPM package resolution [Import strings → ModuleSpecifier]
  3. Fetch and cache module source — Source is fetched from file system or HTTP, cached in GlobalHttpCache, and TypeScript files are transpiled to JavaScript using SWC with configured compiler options [ModuleSpecifier → Module source code]
  4. Initialize V8 isolate with extensions — JsRuntime creates V8 isolate, loads startup snapshot, registers ops from all extensions (fetch, crypto, fs, etc.), and initializes OpState with permissions and resources [Runtime configuration → JsRuntime]
  5. Load and execute JavaScript modules — ModuleLoader provides source to V8, modules are compiled and linked, main module is evaluated, and event loop processes microtasks and op completions [Module source code → Module execution results]
  6. Process op calls between JavaScript and Rust — OpDispatcher handles calls from JavaScript to Rust functions, serializes arguments using serde_v8, executes Rust implementation with permission checks, and returns results to JavaScript [Op calls from JavaScript → Op results to JavaScript]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

OpState libs/core/lib.rs
RefCell-wrapped state container holding per-isolate data including resource registry, permissions, extension state, and op-specific data structures
Created during isolate initialization, mutated during op calls, and cleaned up when isolate shuts down
ModuleSpecifier deno_ast crate
URL-like identifier for modules with scheme (file://, https://, npm:, jsr:) and normalized path/query components
Parsed from import strings, resolved through module graph, and used to fetch/load module source code
Resource libs/core/lib.rs
Trait object with ResourceId, name, and cleanup behavior - concrete types include files, network connections, timers, and crypto operations
Allocated with unique ResourceId, stored in OpState registry, accessed during ops, and cleaned up on close or isolate shutdown
JsRuntime libs/core/lib.rs
V8 isolate wrapper containing OpState, module loader, snapshot data, extensions list, and event loop integration
Created with configuration and snapshot, loads modules, executes JavaScript, processes ops, and manages isolate lifecycle
PermissionsContainer runtime/permissions/lib.rs
Structured permissions with allow/deny lists for network, file system, environment, subprocess, and other capabilities
Initialized from CLI flags and config, queried before resource operations, and can be dynamically modified through permission APIs

Hidden Assumptions

Things this code relies on but never validates. These are the things that cause silent failures when the system changes.

critical Environment unguarded

The JSR_URL lazy static can be safely constructed at runtime using CliSys::default() and will remain valid for the entire program lifetime

If this fails: If the JSR URL resolution fails during first access, the entire program crashes with a panic since Lazy::new() doesn't handle initialization errors gracefully

cli/args/mod.rs:jsr_url
critical Resource unguarded

The snapshot file exists at the path computed by concat!(env!("OUT_DIR"), "/RUNJS_SNAPSHOT.bin") and is valid V8 heap data

If this fails: If build.rs doesn't generate the snapshot or generates corrupt data, include_bytes! will either fail at compile time or the runtime will crash when trying to deserialize invalid V8 heap state

libs/core/examples/snapshot/src/main.rs:RUNTIME_SNAPSHOT
critical Ordering unguarded

The sequence of js_runtime.load_main_es_module(), js_runtime.mod_evaluate(), and js_runtime.run_event_loop() must be called in this exact order without interleaving other operations

If this fails: If the order is changed or operations are interleaved, the module evaluation might not complete properly or the event loop might process tasks before the module is fully loaded, leading to runtime errors or undefined behavior

libs/core/examples/snapshot/src/main.rs:run_js
warning Resource unguarded

The denort::main() function exists and is accessible, presumably from a binary crate dependency

If this fails: If the denort crate is not properly linked or the main function doesn't exist, this will fail at compile time, but there's no fallback or error handling mechanism

cli/rt/main.rs:main
warning Environment weakly guarded

The current working directory exists and is accessible when current_dir() is called

If this fails: If the process doesn't have permission to read the current directory or it was deleted after the process started, current_dir() returns an error that gets propagated up, but the error message may be confusing to users expecting a JavaScript file issue

libs/core/examples/snapshot/src/main.rs:current_dir
warning Scale unguarded

The snapshot binary data included at compile time fits within memory limits and doesn't exceed maximum static data size constraints

If this fails: For very large snapshots, this could cause compilation to fail or result in excessive binary size and memory usage at startup, but there's no size validation or chunking mechanism

ext/fetch/lib.rs:RUNTIME_SNAPSHOT
warning Temporal unguarded

The JSR URL configuration and CliSys default values remain stable between the time the lazy static is initialized and when it's accessed throughout program execution

If this fails: If JSR configuration changes dynamically or CliSys behavior varies based on runtime conditions, the cached URL might become stale or incorrect, leading to failed module resolution

cli/args/mod.rs:JSR_URL lazy static
warning Contract unguarded

The FsModuleLoader is compatible with the RUNTIME_SNAPSHOT and extensions provided, and their initialization order doesn't matter

If this fails: If the snapshot contains state that conflicts with FsModuleLoader expectations or extension initialization, the runtime might initialize successfully but fail unpredictably during module loading

libs/core/examples/snapshot/src/main.rs:RuntimeOptions
info Environment weakly guarded

The file_path parameter refers to a file that exists and is readable when deno_core::resolve_path is called

If this fails: If the file doesn't exist, resolve_path succeeds but load_main_es_module will fail later with a potentially confusing error about module loading rather than file existence

libs/core/examples/snapshot/src/main.rs:resolve_path
info Resource weakly guarded

The tokio runtime can be created with enable_all() and current_thread configuration without conflicting with any existing async runtime or thread pool setup

If this fails: If there's already a tokio runtime active or incompatible async setup, Builder::build() might fail or create a nested runtime that causes deadlocks in async operations

libs/core/examples/snapshot/src/main.rs:tokio runtime

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

GlobalHttpCache (cache)
HTTP responses cached to disk by URL with headers and metadata for offline access and performance
ResourceRegistry (registry)
Maps ResourceId to Resource instances for files, network connections, timers, and other system objects
ModuleMap (registry)
Tracks loaded modules by ModuleSpecifier with compilation state and dependency information
TypeCheckCache (cache)
Stores TypeScript type checking results to avoid recomputation when source hasn't changed

Feedback Loops

Delays

Control Points

Technology Stack

V8 (runtime)
JavaScript engine for executing user code with JIT compilation and garbage collection
Tokio (runtime)
Async runtime providing event loop, futures, and async I/O primitives for non-blocking operations
SWC (build)
TypeScript to JavaScript transpiler integrated for fast compilation of .ts files
Hyper (library)
HTTP client/server implementation used by fetch extension for network requests
Rustls (library)
TLS implementation providing secure connections for HTTPS and WebSocket operations
SQLite (database)
Embedded database for caching compiled modules, type check results, and KV storage
serde_v8 (serialization)
Serialization bridge between Rust data structures and V8 JavaScript values

Key Components

Package Structure

cli (app)
Main Deno CLI binary that orchestrates all runtime operations including argument parsing, module resolution, and execution coordination.
lib (shared)
Shared library components used by CLI including NPM handling, worker management, and system abstractions.
rt (app)
Standalone runtime binary for executing compiled Deno applications without the full CLI toolchain.
runtime (library)
Core runtime components including permissions system, process management, and JavaScript execution environment.
core (library)
Fundamental V8 integration layer providing JavaScript engine bindings, module loading, and op system for Rust-JS communication.
ops (tooling)
Procedural macro system for generating JavaScript-Rust FFI bindings and runtime operation definitions.

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Repository Repositories

Frequently Asked Questions

What is deno used for?

Executes JavaScript and TypeScript with secure defaults and native performance denoland/deno is a 8-component repository written in Rust. Data flows through 6 distinct pipeline stages. The codebase contains 4956 files.

How is deno architected?

deno is organized into 4 architecture layers: CLI Layer, Runtime Layer, Extension Layer, Core Layer. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through deno?

Data moves through 6 stages: Parse CLI arguments and load configuration → Resolve module specifiers → Fetch and cache module source → Initialize V8 isolate with extensions → Load and execute JavaScript modules → .... Source code enters through CLI argument parsing which resolves module specifiers and loads configuration. The module loader fetches source code (local files or remote URLs), TypeScript gets transpiled through SWC/TSC, modules are loaded into V8 isolate, and JavaScript execution proceeds with op calls bridging back to Rust implementations for I/O and system operations. Results flow back through the op system to JavaScript and finally to stdout/files. This pipeline design reflects a complex multi-stage processing system.

What technologies does deno use?

The core stack includes V8 (JavaScript engine for executing user code with JIT compilation and garbage collection), Tokio (Async runtime providing event loop, futures, and async I/O primitives for non-blocking operations), SWC (TypeScript to JavaScript transpiler integrated for fast compilation of .ts files), Hyper (HTTP client/server implementation used by fetch extension for network requests), Rustls (TLS implementation providing secure connections for HTTPS and WebSocket operations), SQLite (Embedded database for caching compiled modules, type check results, and KV storage), and 1 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does deno have?

deno exhibits 4 data pools (GlobalHttpCache, ResourceRegistry), 3 feedback loops, 4 control points, 3 delays. The feedback loops handle recursive and polling. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does deno use?

4 design patterns detected: Extension Pattern, Op System FFI, Resource Management, Snapshot Optimization.

Analyzed on April 20, 2026 by CodeSea. Written by .