Deno — JavaScript Runtime An Toàn TypeScript Native
Deno là runtime JavaScript/TypeScript an toàn mặc định, không npm, TypeScript native. Runtime đơn nhị phân, Web API tương thích, permissions.
Deno là runtime cho JavaScript và TypeScript — tạo bởi chính Ryan Dahl (tác giả Node.js). Học từ sai lầm của Node.
Node.js (2009): npm, node_modules, CommonJS, callback
Deno (2020): URL import, không node_modules, ESM, async/await, TypeScriptplaintextTại Sao Deno?#
Vấn đề với Node.js#
Ryan Dahl liệt kê 10 điều hối tiếc về Node trong bài talk “10 Things I Regret About Node.js”:
- Promise thay vì callback (đã fix)
- Security (không sandbox)
- Module system (CommonJS vs ESM mess)
- node_modules nặng
- package.json phình to
- TypeScript không native
Deno giải quyết tất cả.
So Sánh#
| Node.js | Deno | |
|---|---|---|
| TypeScript | Cần tsconfig + ts-node | Native |
| Module | npm + node_modules | URL import + npm (JSR) |
| Security | Full access | Permissions opt-in |
| Package manager | npm/yarn/pnpm | Không cần |
| Config | package.json, tsconfig,… | deno.json (tuỳ chọn) |
| Standard library | npm packages | std (deno.land/std) |
| Web API | fetch, AbortController… | ✅ All Web API |
| Binary | 1 file? | 1 file (~30MB) |
Cài Đặt#
# macOS / Linux
curl -fsSL https://deno.land/install.sh | sh
# macOS (Homebrew)
brew install deno
# Windows
winget install DenoLand.Deno
# Verify
deno --version
deno --helpbashHello World#
// hello.ts
console.log('Hello Deno!')
// Chạy — không cần config, không cần package.json
deno run hello.tstypescript# Cấp quyền network
deno run --allow-net server.ts
# Cấp quyền đọc file
deno run --allow-read file.ts
# Cấp tất cả (không khuyến khích)
deno run -A script.tsbashPermissions#
Deno an toàn mặc định — script không có quyền gì:
// Không chạy được — cần --allow-net
const res = await fetch('https://api.example.com')
// Không chạy được — cần --allow-read
const text = await Deno.readTextFile('/etc/hosts')
// Không chạy được — cần --allow-env
console.log(Deno.env.get('HOME'))typescript# Grant từng quyền
deno run --allow-net=api.example.com --allow-read=/tmp script.ts
# Prompt quyền khi cần (interactive)
deno run --allow-prompt script.tsbashPermissions: --allow-read, --allow-write, --allow-net, --allow-env, --allow-run, --allow-ffi, --allow-sys, --allow-hrtime.
TypeScript Native#
// Chạy TypeScript trực tiếp — không tsconfig.json
// Deno tự compile, cache type definitions
interface User {
id: number
name: string
email: string
}
const user: User = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
}
// Deno tự động download type definitions
import { serve } from 'https://deno.land/std@0.224.0/http/server.ts'typescript// deno.json — optional config (thay thế package.json + tsconfig)
{
"tasks": {
"dev": "deno run --watch --allow-net src/main.ts",
"start": "deno run --allow-net --allow-read src/main.ts",
"test": "deno test"
},
"imports": {
"express": "npm:express@5",
"std/": "https://deno.land/std@0.224.0/"
}
}jsonModule: URL Import#
Không npm install, không node_modules:
// Import từ URL — Deno cache tự động
import { serve } from 'https://deno.land/std@0.224.0/http/server.ts'
import { Hono } from 'https://deno.land/x/hono/mod.ts'
// Import từ npm (Deno 2+)
import express from 'npm:express@5'
// Import từ JSR (Deno registry mới)
import { z } from 'jsr:@std/zod'typescriptCache ở:
~/.cache/deno/ (macOS/Linux)
%LOCALAPPDATA%/deno/ (Windows)plaintextKhông npm install, không node_modules, không package-lock.json cho URL imports.
HTTP Server#
// Web API chuẩn — Request/Response như browser
Deno.serve({ port: 3000 }, (req) => {
const url = new URL(req.url)
if (req.method === 'GET' && url.pathname === '/') {
return new Response('Hello Deno!', {
headers: { 'content-type': 'text/plain' },
})
}
if (req.method === 'GET' && url.pathname === '/api/users') {
const users = [{ id: 1, name: 'Alice' }]
return Response.json(users)
}
return new Response('Not Found', { status: 404 })
})
console.log('Server running on http://localhost:3000')typescriptdeno run --allow-net server.tsbashFile System#
// Deno API — promise-based
const content = await Deno.readTextFile('./data.json')
const data = JSON.parse(content)
await Deno.writeTextFile('./output.txt', 'Hello Deno!')
// Web API
const json = await Deno.readTextFile('./config.json')
const config = JSON.parse(json)
// Streaming
const file = await Deno.open('./large-file.txt')
for await (const chunk of file.readable) {
// process chunk
}typescriptStandard Library#
Deno có std library chính thức — không cần npm packages cho common tasks:
// std/fs
import { walk } from 'https://deno.land/std@0.224.0/fs/walk.ts'
for await (const entry of walk('./src')) {
console.log(entry.path)
}
// std/path
import { join, extname } from 'https://deno.land/std@0.224.0/path/mod.ts'
const fullPath = join('src', 'components', 'Header.tsx')
console.log(extname(fullPath)) // .tsx
// std/csv
import { parse } from 'https://deno.land/std@0.224.0/csv/parse.ts'
const records = parse(csvString)
// std/testing
import { assertEquals } from 'https://deno.land/std@0.224.0/assert/mod.ts'
Deno.test('should add', () => {
assertEquals(1 + 1, 2)
})typescriptTesting#
Testing built-in — không cần Jest/Vitest:
// math_test.ts
import { assertEquals } from 'https://deno.land/std@0.224.0/assert/mod.ts'
Deno.test('add two numbers', () => {
const result = 1 + 2
assertEquals(result, 3)
})
Deno.test('async test', async () => {
const res = await fetch('https://api.example.com')
assertEquals(res.status, 200)
})typescript# Chạy test
deno test
deno test --allow-net # Nếu test cần network
deno test --watch # Watch mode
deno test --coverage # CoveragebashDeno 2.x Features#
Deno 2 (2024+) thêm tương thích ngược với Node.js/npm:
{
"imports": {
"express": "npm:express@5",
"react": "npm:react@19",
"lodash": "npm:lodash@4"
}
}json// Chạy package.json project với Deno
deno run npm:next start
// Dùng npm packages
import express from 'npm:express@5'
const app = express()
app.get('/', (req, res) => res.send('Hello from Deno!'))
app.listen(3000)typescriptDeno 2 có thể chạy hầu hết Node.js projects — chỉ cần deno run thay node.
So Sánh: Node vs Deno#
// Node.js
const http = require('http')
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end('Hello Node\n')
}).listen(3000)
// Deno
Deno.serve({ port: 3000 }, (req) => {
return new Response('Hello Deno')
})
// Deno dùng Web API — giống browsertypescript| Task | Node | Deno |
|---|---|---|
| HTTP server | http.createServer | Deno.serve (Web API) |
| File read | fs.readFileSync | Deno.readTextFile |
| Environment | process.env | Deno.env.get |
| TypeScript | ts-node, tsconfig | Native |
| Test | Jest, Vitest | Deno.test |
| Format | Prettier | deno fmt |
| Lint | ESLint | deno lint |
| Compile | pkg, nexe | deno compile |
Toolchain#
Deno là runtime + toolchain trong một binary:
deno run # Run script
deno test # Test runner
deno fmt # Formatter (Prettier alternative)
deno lint # Linter (ESLint alternative)
deno doc # Documentation generator
deno compile # Compile to single binary
deno bench # Benchmark runner
deno task # Run tasks (package.json scripts)
deno check # Type-check
deno init # Init projectbash# Format code
deno fmt
# Lint
deno lint
# Compile thành binary standalone
deno compile --allow-net --output my-app src/main.ts
# → my-app (single binary, ~30MB, chạy không cần Deno)bashKhi Nào Dùng Deno?#
✅ Nên dùng#
- CLI tool / script — TypeScript native, không config
- HTTP API nhỏ-gọn — Deno.serve + std library đủ
- Security-sensitive app — permissions model
- New project — không muốn npm baggage
- Single binary distribution — deno compile
❌ Không nên#
- Large Node.js project — migration không đáng
- Cần nhiều npm packages — Node ecosystem vẫn lớn hơn
- Team quen Node — không cần đổi nếu đang ổn
- Serverless (Lambda) — Deno hỗ trợ nhưng Node nhiều hơn
Tổng Kết#
Deno sửa những gì Node làm sai — security, modules, TypeScript, toolchain.
# Deno: một binary cho mọi thứ
deno run --allow-net server.ts # Run server
deno test # Test
deno fmt # Format
deno lint # Lint
deno compile # Build binary
deno doc # Docs
# Không npm install, không node_modules, không tsconfig
# Chỉ import từ URL, chạy luônbash| Node.js | Deno | |
|---|---|---|
| Security | ❌ Full access | ✅ Permissions |
| TypeScript | ❌ tsconfig + ts-node | ✅ Native |
| Module | ❌ npm + node_modules | ✅ URL import + npm |
| Toolchain | ❌ Rời rạc (ESLint, Prettier, Jest) | ✅ Một binary |
| Web API | ⚠️ Một phần | ✅ Đầy đủ |
| Standard lib | ✅ Qua npm | ✅ std + JSR |
Deno không “thay thế Node” — nó là alternative cho những ai muốn runtime an toàn hơn, TypeScript native, ít toolchain hơn.