Introduction to Deno
Definition and Design Philosophy of Deno
Definition:
Deno is a modern JavaScript/TypeScript runtime developed by Ryan Dahl, the creator of Node.js. Built on the V8 engine and Rust, it aims to address historical design issues in Node.js.
Core Design Philosophy:
- Security First: Default sandbox environment requiring explicit permission declarations.
- Built-in Toolchain: Integrated package management, testing, formatting, and other tools.
- Web Standards Compliance: High compatibility with browser APIs.
- Simplified Dependency Management: ES module import system based on URLs.
Core Features of Deno
| Feature | Description |
|---|---|
| Default Security | No access to file system, network, or environment variables without permissions. |
| Native ES Module Support | Supports ES modules natively, abandoning CommonJS. |
| Native TypeScript Support | Runs TypeScript code without additional configuration. |
| Unified Dependency Management | Imports remote modules via URLs with built-in dependency caching. |
| Integrated Modern Toolchain | Includes tools for testing, formatting, linting, and bundling. |
Application Scenarios for Deno
- Web Development: Building API services and real-time applications (WebSocket).
- Scripting Tools: Automating tasks and system management scripts.
- Backend Services: Microservices and Serverless functions.
- Frontend Toolchain: Replacing tools like Webpack or Vite.
- Edge Computing: Developing edge applications with the Fresh framework.
Deno’s Development History and Ecosystem
Development Milestones:
- 2018: Ryan Dahl publishes “10 Things I Regret About Node.js.”
- May 2020: Deno 1.0 officially released.
- 2021: Deno Deploy (edge computing platform) launched.
- 2022: Deno Company established, focusing on enterprise support.
- 2023: Fresh framework released, enhancing full-stack capabilities.
Ecosystem Status:
- Official Frameworks: Oak (HTTP middleware), Fresh (full-stack framework).
- Popular Community Projects: Aleph.js (React framework), Ultra (lightweight framework).
- Tool Libraries: Standard library (std) includes HTTP, file system, and other core modules.
- Deployment Platform: Deno Deploy (global edge network).
Differences Between Deno and Node.js
| Comparison Dimension | Deno | Node.js |
|---|---|---|
| Runtime Design | Based on Rust + V8, security-first | Based on C++ + V8, functionality-first |
| Module System | Native ES modules, URL imports | Supports CommonJS and ES modules |
| Security Model | Default sandbox, explicit permissions | No sandbox, full permissions by default |
| Package Management | Built-in URL-based imports | Relies on npm and package.json |
| TypeScript Support | Native support | Requires additional configuration |
| Startup Speed | Slower (cold start) | Faster |
| Standard Library | Officially maintained std library | Relies on community modules |
Deno’s History and Goals
Deno is a modern JavaScript/TypeScript runtime developed by Ryan Dahl, launched in 2020. Its primary goal is to address Node.js’s historical design flaws, providing a safer and more modern development experience. Key design goals include:
- Default security (sandbox environment).
- Native TypeScript support.
- Unified module system (URL-based ES modules).
- Integrated modern toolchain.
- Reduced core API surface, relying on community standards.
Setting Up the Development Environment
Installation and Configuration
Installation Methods:
# Official installation script
curl -fsSL https://deno.land/x/install/install.sh | sh
# Configure environment variables (automatically added after installation)
export DENO_INSTALL="/home/user/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"Verify Installation:
deno --version
# Example output: deno 1.35.0 (release, x86_64-apple-darwin)
deno info
# Displays installation path and configuration detailsCreating a Deno Project
Initialize a Project:
mkdir deno-project
cd deno-project
touch main.tsRecommended Project Structure:
deno-project/
├── deps.ts # Centralized dependency management
├── src/
│ ├── main.ts # Main entry file
│ └── utils.ts # Utility functions
├── tests/ # Test files
└── deno.json # Project configurationDevelopment Tools
VS Code Configuration:
- Install the official “Deno” plugin.
- Configure
.vscode/settings.json:
{
"deno.enable": true,
"deno.lint": true,
"deno.unstable": false,
"editor.formatOnSave": true,
"typescript.tsdk": "node_modules/typescript/lib"
}Common Plugins:
- Deno
- TypeScript Importer
- Error Lens
Debugging Tools
Chrome DevTools Debugging:
deno run --inspect-brk main.ts
# Access chrome://inspect in ChromeDeno Debug Mode:
deno run --v8-flags=--inspect main.tsDebug Configuration Example:
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Deno Debug",
"runtimeExecutable": "deno",
"runtimeArgs": ["run", "--inspect-brk", "--allow-all", "main.ts"],
"port": 9229
}
]
}Sample Project and Demo Execution
HTTP Server Example:
// server.ts
import { serve } from "https://deno.land/std@0.140.0/http/server.ts"
const server = serve({ port: 8000 })
console.log("Server running on http://localhost:8000")
for await (const req of server) {
req.respond({ body: "Hello Deno!\n" })
}Run:
deno run --allow-net server.tsFile Operation Example:
// file.ts
import { ensureFile, writeJson } from "https://deno.land/std@0.140.0/fs/mod.ts"
await ensureFile("data.json")
await writeJson("data.json", { message: "Hello Deno" })Run:
deno run --allow-write file.tsDeno CLI Basics
Using the deno help Command
deno help # Displays main help information
deno help run # Displays help for the run subcommand
deno run --help # Same as aboveBasic Commands
| Command | Description |
|---|---|
deno run | Runs script files |
deno cache | Caches dependencies |
deno eval | Executes code strings directly |
deno fmt | Formats code |
deno lint | Performs static code analysis |
deno test | Runs tests |
deno bundle | Bundles scripts into a single file |
deno install | Installs scripts as executable programs |
Deno Core Architecture
Deno’s Runtime Architecture
Core Components:
- V8 Engine: Handles JavaScript/TypeScript execution.
- Rust Runtime: Provides low-level system interactions and security controls.
- Permission System: Manages access to files, network, and environment variables.
- Module Cache: URL-based dependency caching mechanism.
- Standard Library (std): Officially maintained core functionality modules.
Architecture Diagram:
[User Code]
→ [Deno Runtime (Rust)]
→ [V8 Engine]
→ [System APIs (Permission Control)]
→ [Standard Library (std)]Deno’s Module System
ES Module Features:
- Requires full file extensions (e.g.,
.ts/.js). - Prohibits Node.js globals like
__dirnameand__filename. - Dependency resolution based on URLs instead of file paths.
URL Import Example:
// Import remote module
import { serve } from "https://deno.land/std@0.140.0/http/server.ts"
// Import local module
import { helper } from "./utils.ts"
// Import from GitHub repository
import { debounce } from "https://raw.githubusercontent.com/lucascaro/deno-debounce/master/mod.ts"Caching Mechanism:
- Downloads and caches to
$DENO_DIR(default~/.deno/dir) on first import. - Subsequent runs use cached versions.
- Use
deno cacheto manually pre-cache dependencies.
Deno’s Security Model
Permission System:
| Permission Type | Scope | Example Flag |
|---|---|---|
| File System | Read/write operations | --allow-read, --allow-write |
| Network | Connect to specific domains/IPs | --allow-net=api.example.com |
| Environment Variables | Read system environment variables | --allow-env |
| Subprocess Execution | Launch external programs | --allow-run |
| High-Precision Timing | performance.now() and similar | --allow-hrtime |
Sandbox Mechanism:
- No permissions by default.
- Granular control over specific resources.
- Runtime dynamic permission checks.
- Query current permission status via
Deno.permissionsAPI.
Deno’s Built-in Toolchain
Core Tools:
- Package Management: Import dependencies directly via URLs.
- Test Framework: Built-in
deno testcommand. - Code Formatting:
deno fmtcommand. - Static Analysis:
deno lintcommand. - Bundling Tool:
deno bundlecommand. - Documentation Generation:
deno doccommand.
Tool Usage Examples:
# Format code
deno fmt *.ts
# Run tests (requires read/write permissions)
deno test --allow-read --allow-write
# Static analysis
deno lint
# Bundle project
deno bundle main.ts bundle.jsDeno’s API Design
Browser Compatibility:
- Supports
fetch,WebSocket, and other Web APIs. - Extends browser APIs with the
Denonamespace. - Compatible with parts of
WindowandWorkerenvironments.
Typical API Examples:
// File system operations (requires permissions)
await Deno.writeFile("file.txt", new TextEncoder().encode("Hello"))
// Network requests
const resp = await fetch("https://api.example.com")
const data = await resp.json()
// Environment variables (requires permissions)
const env = Deno.env.toObject()
// Permission checks
const status = await Deno.permissions.query({ name: "read" })Module System
ES Module Imports and Exports
Create math.ts:
export function add(a: number, b: number): number {
return a + b;
}
export function sub(a: number, b: number): number {
return a - b;
}Create main.ts:
import { add, sub } from "./math.ts";
console.log(add(4, 2)); // 6
console.log(sub(4, 2)); // 2Run:
deno run main.tsUsing URL Imports for Remote Modules
// Import directly from URL
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
const server = serve({ port: 8000 });
console.log("HTTP server running on http://localhost:8000");
for await (const req of server) {
req.respond({ body: "Hello Deno!\n" });
}Run with network permissions:
deno run --allow-net server.tsPermission Management
Permission Flags
| Permission Flag | Description |
|---|---|
--allow-read | Allows file system reading |
--allow-write | Allows file system writing |
--allow-net | Allows network access |
--allow-env | Allows environment variable access |
--allow-run | Allows subprocess execution |
--allow-plugin | Allows plugin loading (deprecated) |
--allow-hrtime | Allows high-precision time measurement |
Combined usage example:
deno run --allow-read=/etc --allow-net=api.example.com script.ts
Security Sandbox Model
Deno runs in a strict security sandbox by default:
- No file system access.
- No network access.
- No environment variable access.
- No subprocess execution.
- No plugin loading.
Permissions must be explicitly granted via command-line flags.
Configuration File
Creating a Configuration File
Create deno.json:
{
"tasks": {
"start": "deno run --allow-net server.ts",
"test": "deno test --allow-read=./data"
},
"imports": {
"std": "https://deno.land/std@0.140.0/",
"lodash": "https://cdn.skypack.dev/lodash@4.17.21"
},
"compilerOptions": {
"strict": true
}
}Practice: Configuring Dependencies
Using import mappings from the configuration file:
// main.ts
import { serve } from "std/http/server.ts"
import { camelCase } from "lodash"
console.log(camelCase("hello world"))
serve({ port: 8000 }, (req) => new Response("Hello Deno"))Run:
deno run --allow-net main.tsWeb Frameworks
Fresh
An emerging full-stack framework focused on server components and edge computing:
deno install -qAf --unstable https://deno.land/x/fresh/cli.ts
fresh init my-project
cd my-project
deno task startAleph.js
A React framework similar to Next.js:
deno install -qAf https://deno.land/x/aleph/cli.ts
aleph init my-project
cd my-project
deno run --allow-net dev.tsUltra
A high-performance framework emphasizing minimalist API design:
deno install -qAf https://deno.land/x/ucli@0.1.0/cli.ts
ultra init my-project
cd my-project
deno run --allow-net server.tsLume
A static site generator:
deno install -qAf https://deno.land/x/lume/cli.ts
lume init my-project
cd my-project
deno task buildOak
An Express-like middleware framework:
// server.ts
import { Application, Router } from "https://deno.land/x/oak/mod.ts"
const app = new Application()
const router = new Router()
router.get("/", (ctx) => {
ctx.response.body = "Hello Oak!"
})
app.use(router.routes())
app.use(router.allowedMethods())
await app.listen({ port: 8000 })Run:
deno run --allow-net server.tsType Checking and Compilation
Native TypeScript Support
Deno natively supports TypeScript:
// Type checking example
function greet(name: string): string {
return `Hello, ${name}!`
}
console.log(greet("Deno")) // Correct
// console.log(greet(123)) // Compilation errorUsing .ts Files and Type Checking
Create types.ts:
export interface User {
id: number
name: string
email?: string
}
export function createUser(name: string, email?: string): User {
return {
id: Math.random(),
name,
email
}
}Create main.ts:
import { User, createUser } from "./types.ts"
const user: User = createUser("Alice", "alice@example.com")
console.log(user)Run:
deno run --allow-read main.ts
# Or use caching
deno cache main.ts
deno run main.tsCompiling to JavaScript
deno compile --allow-net server.ts
# Generates platform-specific executable
./server # Linux/macOS
server.exe # Windows



