Deno: Orientation
Deno is a useful concurrency study because it connects two asynchronous worlds: JavaScript promises inside V8 and Rust futures driven by an event loop. It also has to expose operating-system capabilities without allowing JavaScript to own Rust objects directly.
JavaScript API
↓ calls a generated op
Rust permission check → async filesystem/network future
↓ pending op driver
Tokio + operating system readiness
↓ completed op
V8 event-loop turn → resolve/reject Promise → run microtasks
Design thesis
Deno keeps each V8 isolate locally owned, exposes native capabilities as typed Rust ops, and returns async completions to JavaScript through an explicit event loop.
That sentence contains the important boundaries:
- A worker owns a V8 isolate and its JavaScript state.
- An op is a typed Rust function exposed to JavaScript.
OpStatestores runtime services such as permissions and the resource table.- A resource ID, or
rid, lets JavaScript refer to an owned Rust resource. - The op driver holds heterogeneous pending Rust futures behind one runtime interface.
- The event loop decides when completed ops, timers, modules, messages, and promise microtasks are advanced.
What to preserve while reading
Do not begin with every web API or command-line flag. Preserve these five architectural facts:
- JavaScript cannot directly borrow a Rust socket across an
await. - Permission checks happen at the native capability boundary.
- Pending I/O does not block the isolate’s operating-system thread.
- V8 is re-entered on the isolate owner, not from arbitrary completion threads.
- Long-lived native objects have explicit identity and cleanup.
The runtime crate assembles workers, libs/core owns the V8/op/event-loop
machinery, and ext implements capabilities such as files, networking, HTTP,
and web APIs. That separation is the first map to keep in your head.