2.2 Overall architecture
Last updated
Last updated
Similar to other runtime environments like Node.js, Bun, Go, and Python, Deno operates as a compact monolith within a single process. This design approach is common among major runtime environments, leveraging multi-threading capabilities to efficiently handle computationally intensive tasks. Notably, Go distinguishes itself by providing robust support for green threads, enhancing performance in specific scenarios.
Deno's foundation uniquely spans multiple programming languages, with core components built using Rust, TypeScript, and JavaScript. Interestingly, Deno's primary runtime, initially written in TypeScript, has been rewritten in pure JavaScript, without ES modules, showcasing Deno's adaptability and dynamic development process.
Deno's intricate operations rely on seven pivotal components, which synergize to execute diverse tasks. Beyond these core components, three essential third-party libraries enrich the ecosystem, enabling JavaScript program execution while maintaining asynchronous internal mechanisms. This balance of native and third-party components enables Deno to seamlessly run JavaScript programs while upholding its asynchronous nature.
In total, Deno's architecture comprises approximately 10 components, categorized into seven core and three third-party blocks. These blocks form the essential building blocks of Deno's functionality and features, underscoring its robust and adaptable design.
The following block diagram illustrates the key building blocks that constitute Deno's native architecture. This diagram provides a comprehensive overview of the main components developed and maintained by the Deno team. Please note that this diagram exclusively focuses on Deno's native components and does not include any elements contributed by third-party sources. This distinction is important, as it highlights the core components that form the foundation of Deno's runtime environment, separate from external libraries and dependencies.
Before we proceed to a detailed examination of Deno's architecture, let us first take a brief look at the principal components that comprise this runtime environment. While we will explore each of these components in greater depth in subsequent sections, this initial overview will provide a foundational understanding of Deno's functionality and the role each component plays in its overall framework. This introduction will set the stage for a more comprehensive analysis of Deno's inner workings.
In addition to relying on essential third-party components like Tokio and V8, Deno's user-facing functionality is largely integrated into the Command-Line Interface (CLI). The CLI serves as a central hub, fulfilling two critical roles: orchestration and execution. By connecting various components, the CLI plays a vital role in facilitating user interaction with Deno's core features and functionality.
The runtime component is a crucial aspect of Deno's architecture, encompassing a range of essential elements. These include:
Deno's runtime code, written in JavaScript
Fundamental operations at a lower level
An inspector for debugging purposes
Performance metrics
Key functionalities, such as:
Main worker
Web worker
Permissions control
This component plays a central role in executing Deno's core functionality, managing worker processes, and enforcing security permissions, while also providing critical tools for debugging and performance measurement.
The ext component is a collection of compact, modular blocks that provide a range of web APIs. These modules are designed to be self-contained and flexible, offering a variety of web-related functionalities that can be easily integrated into Deno's runtime environment.
The Core component plays a vital role in Deno's architecture, serving as a bridge between the Rust and JavaScript layers. On one hand, it collaborates with the Rust components, including the CLI and the runtime, to facilitate seamless interaction. On the other hand, it provides a range of services that can be easily accessed from the Deno runtime using JavaScript.
While the CLI orchestrates the execution, the Core component provides critical functionality for running TypeScript/JavaScript code and enabling interoperability between JavaScript and Rust. Specifically, the Core implements essential features such as:
V8 bindings
Flags
Modules
JsRuntime
Zero overhead bindings
Shared queue
The primary purpose of the Core component is to provide low-level functionality that enables efficient communication between the Rust and JavaScript layers.
The Graph component provides module graph services to the CLI component. The module graph is a visual representation of the relationships between various modules in a Deno project, illustrating their dependencies and interconnections. By offering a comprehensive view of module relationships, the Graph component enables the CLI to efficiently manage and resolve dependencies.
The NPM component serves as an interface between Deno and the Node Package Manager (NPM) ecosystem, providing a set of APIs specifically designed for interacting with NPM modules.
The Cache component is a vital part of Deno's architecture, responsible for managing and maintaining the module cache within the runtime environment. This cache contains modules sourced from diverse locations, including the NPM repository, as well as other external sources. By efficiently managing the module cache, the Cache component ensures rapid access to frequently used modules, reduces loading times, and enhances overall performance.
Although not depicted in the diagram, the Rusty_v8 component is a crucial element in the Deno project. It provides high-quality Rust bindings to V8's C++ API, effectively serving as a bridge between the Rust programming language and V8's core functionalities. By offering a reliable and efficient interface, Rusty_v8 enables seamless communication between Rust and V8, facilitating the integration of V8's powerful engine with Rust's memory safety guarantees.
Although Deno's core components are essential for its operation, they are insufficient on their own to execute tasks. To attain its full functionality, Deno relies on critical external components that act as the backbone of the Deno runtime. These external components, including Tokio and V8, among others, play a vital role in enabling Deno's to run JS code.
Tokio, a crucial third-party component, plays a central role in Deno's architecture, serving as the foundation upon which Deno's asynchronous capabilities are built. The harmonious integration of Tokio empowers Deno to unlock its full asynchronous potential, enabling the efficient execution of concurrent tasks.
JavaScript programs rely on the presence of a JavaScript engine to execute, and V8 is a prominent example of such an engine. Developed by Google, V8 is an open-source, high-performance engine specifically designed for executing JavaScript and WebAssembly code. Built using the C++ programming language, V8 plays a vital role in powering JavaScript execution, enabling the runtime environment to interpret and execute JavaScript code efficiently.
The TypeScript compiler is a crucial third-party component in Deno, though not depicted in the diagram. As previously mentioned, V8 solely processes JavaScript code. However, Deno supports both TypeScript (TS) and JavaScript (JS). To allow TypeScript, Deno uses the TypeScript compiler to transform TypeScript code into JavaScript before presenting it to V8 for execution. This process enables Deno to have built-in support for TypeScript applications.
--
This section has provided a comprehensive overview of Deno's architecture, highlighting the key components that comprise its structure. We have briefly examined the roles and relationships between these components, gaining a foundational understanding of Deno's inner workings. In the next section, we will examine each component in more detail, analyzing their functions and characteristics.