Lesson 14-Deno Basics Introduction

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

FeatureDescription
Default SecurityNo access to file system, network, or environment variables without permissions.
Native ES Module SupportSupports ES modules natively, abandoning CommonJS.
Native TypeScript SupportRuns TypeScript code without additional configuration.
Unified Dependency ManagementImports remote modules via URLs with built-in dependency caching.
Integrated Modern ToolchainIncludes 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 DimensionDenoNode.js
Runtime DesignBased on Rust + V8, security-firstBased on C++ + V8, functionality-first
Module SystemNative ES modules, URL importsSupports CommonJS and ES modules
Security ModelDefault sandbox, explicit permissionsNo sandbox, full permissions by default
Package ManagementBuilt-in URL-based importsRelies on npm and package.json
TypeScript SupportNative supportRequires additional configuration
Startup SpeedSlower (cold start)Faster
Standard LibraryOfficially maintained std libraryRelies 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 details

Creating a Deno Project

Initialize a Project:

mkdir deno-project
cd deno-project
touch main.ts

Recommended 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 configuration

Development Tools

VS Code Configuration:

  1. Install the official “Deno” plugin.
  2. 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 Chrome

Deno Debug Mode:

deno run --v8-flags=--inspect main.ts

Debug 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.ts

File 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.ts

Deno 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 above

Basic Commands

CommandDescription
deno runRuns script files
deno cacheCaches dependencies
deno evalExecutes code strings directly
deno fmtFormats code
deno lintPerforms static code analysis
deno testRuns tests
deno bundleBundles scripts into a single file
deno installInstalls scripts as executable programs

Deno Core Architecture

Deno’s Runtime Architecture

Core Components:

  1. V8 Engine: Handles JavaScript/TypeScript execution.
  2. Rust Runtime: Provides low-level system interactions and security controls.
  3. Permission System: Manages access to files, network, and environment variables.
  4. Module Cache: URL-based dependency caching mechanism.
  5. 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 __dirname and __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 cache to manually pre-cache dependencies.

Deno’s Security Model

Permission System:

Permission TypeScopeExample Flag
File SystemRead/write operations--allow-read, --allow-write
NetworkConnect to specific domains/IPs--allow-net=api.example.com
Environment VariablesRead system environment variables--allow-env
Subprocess ExecutionLaunch external programs--allow-run
High-Precision Timingperformance.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.permissions API.

Deno’s Built-in Toolchain

Core Tools:

  1. Package Management: Import dependencies directly via URLs.
  2. Test Framework: Built-in deno test command.
  3. Code Formatting: deno fmt command.
  4. Static Analysis: deno lint command.
  5. Bundling Tool: deno bundle command.
  6. Documentation Generation: deno doc command.

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.js

Deno’s API Design

Browser Compatibility:

  • Supports fetch, WebSocket, and other Web APIs.
  • Extends browser APIs with the Deno namespace.
  • Compatible with parts of Window and Worker environments.

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)); // 2

Run:

deno run main.ts

Using 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.ts

Permission Management

Permission Flags

Permission FlagDescription
--allow-readAllows file system reading
--allow-writeAllows file system writing
--allow-netAllows network access
--allow-envAllows environment variable access
--allow-runAllows subprocess execution
--allow-pluginAllows plugin loading (deprecated)
--allow-hrtimeAllows 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.ts

Web 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 start

Aleph.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.ts

Ultra

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.ts

Lume

A static site generator:

deno install -qAf https://deno.land/x/lume/cli.ts
lume init my-project
cd my-project
deno task build

Oak

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.ts

Type 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 error

Using .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.ts

Compiling to JavaScript

deno compile --allow-net server.ts
# Generates platform-specific executable
./server # Linux/macOS
server.exe # Windows
Share your love