Deno Core Knowledge
Full Reference: See advanced.md for production readiness, testing patterns, middleware, Deno Deploy, and npm compatibility.
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: deno for comprehensive documentation.
Basics
Running Scripts
Run a TypeScript file
deno run main.ts
Run with permissions
deno run --allow-net --allow-read main.ts
Run remote script
deno run https://deno.land/std/examples/welcome.ts
Check/compile without running
deno check main.ts
TypeScript Native
// main.ts - TypeScript works out of the box interface User { id: number; name: string; email: string; }
async function fetchUser(id: number): Promise<User> {
const response = await fetch(https://api.example.com/users/${id});
return await response.json();
}
// Top-level await - no async wrapper needed const user = await fetchUser(1); console.log(user.name);
Permissions
Permission Types
Flag Description
--allow-read
File system read access
--allow-write
File system write access
--allow-net
Network access
--allow-env
Environment variable access
--allow-run
Subprocess execution
--allow-ffi
Foreign function interface
--allow-sys
System information
-A or --allow-all
All permissions
Granular Permissions
Specific paths
deno run --allow-read=/etc,/tmp script.ts
Specific hosts
deno run --allow-net=api.example.com,db.example.com:5432 script.ts
Specific environment variables
deno run --allow-env=DATABASE_URL,API_KEY script.ts
Runtime Permission Requests
// Request permission at runtime const status = await Deno.permissions.request({ name: "read", path: "/etc" }); if (status.state === "granted") { const data = await Deno.readTextFile("/etc/passwd"); }
// Query current permission const netStatus = await Deno.permissions.query({ name: "net", host: "api.example.com" }); console.log(netStatus.state); // "granted", "denied", or "prompt"
Standard Library
File System
// Read file const content = await Deno.readTextFile("./data.txt");
// Write file await Deno.writeTextFile("./output.txt", "Hello, World!");
// Read directory for await (const entry of Deno.readDir("./")) { console.log(entry.name, entry.isFile, entry.isDirectory); }
// File info const stat = await Deno.stat("./file.txt"); console.log(stat.size, stat.mtime);
// Copy/remove files await Deno.copyFile("./src.txt", "./dest.txt"); await Deno.remove("./temp.txt"); await Deno.remove("./temp-dir", { recursive: true });
Path Operations
import { join, basename, dirname, extname } from "https://deno.land/std/path/mod.ts";
const fullPath = join("home", "user", "documents", "file.txt"); console.log(basename(fullPath)); // "file.txt" console.log(dirname(fullPath)); // "home/user/documents" console.log(extname(fullPath)); // ".txt"
Async Utilities
import { delay } from "https://deno.land/std/async/delay.ts"; import { deadline } from "https://deno.land/std/async/deadline.ts";
// Delay await delay(1000); // Wait 1 second
// Deadline (timeout) try { const result = await deadline(fetchData(), 5000); // 5 second timeout } catch (e) { if (e instanceof DeadlineError) { console.log("Request timed out"); } }
Deno.serve (Modern HTTP)
Basic Server
Deno.serve((req: Request) => { return new Response("Hello, World!"); });
With Configuration
Deno.serve({
port: 8000,
hostname: "0.0.0.0",
onListen: ({ port, hostname }) => {
console.log(Server started at http://${hostname}:${port});
},
}, handler);
Routing
Deno.serve((req: Request) => { const url = new URL(req.url); const { pathname } = url;
if (req.method === "GET" && pathname === "/") { return new Response("Home"); }
if (req.method === "GET" && pathname === "/api/users") { return Response.json(users); }
if (req.method === "POST" && pathname === "/api/users") { return handleCreateUser(req); }
// Pattern matching const userMatch = pathname.match(/^/api/users/(\d+)$/); if (userMatch && req.method === "GET") { const userId = parseInt(userMatch[1]); return Response.json(users.find(u => u.id === userId)); }
return new Response("Not Found", { status: 404 }); });
Testing
Basic Tests
import { assertEquals, assertThrows } from "https://deno.land/std/assert/mod.ts";
Deno.test("simple test", () => { assertEquals(1 + 1, 2); });
Deno.test("async test", async () => { const response = await fetch("https://api.example.com/health"); assertEquals(response.status, 200); });
Deno.test("throws test", () => { assertThrows( () => { throw new Error("boom"); }, Error, "boom" ); });
Running Tests
Run all tests
deno test
Run specific file
deno test user_test.ts
With permissions
deno test --allow-net --allow-read
Watch mode
deno test --watch
Coverage
deno test --coverage=coverage deno coverage coverage --lcov > coverage.lcov
deno.json Configuration
{ "tasks": { "dev": "deno run --watch --allow-net main.ts", "start": "deno run --allow-net main.ts", "test": "deno test --allow-read" }, "imports": { "@std/": "https://deno.land/std@0.210.0/", "express": "npm:express@4", "zod": "npm:zod" }, "compilerOptions": { "strict": true } }
When NOT to Use This Skill
Scenario Use Instead
Node.js runtime specifics nodejs skill
Fresh framework Framework-specific skill
Oak framework Framework-specific skill
TypeScript syntax typescript skill
npm package ecosystem nodejs skill
Anti-Patterns
Anti-Pattern Why It's Bad Correct Approach
Using --allow-all Defeats security model Grant specific permissions
Not versioning imports Breaking changes Pin versions in imports
Ignoring lock file Reproducibility issues Commit deno.lock
Mixing npm: and https: imports Inconsistent deps Prefer one approach
Not handling permission errors Runtime failures Check permissions first
Synchronous file I/O Blocks runtime Use async Deno APIs
No error boundaries Unhandled errors Add error middleware
Hardcoded URLs Portability issues Use environment variables
Quick Troubleshooting
Issue Cause Solution
"PermissionDenied" Missing permission flag Add --allow-* flag
"Module not found" Wrong URL or version Check import URL
"Integrity check failed" Lock file mismatch Run with --lock-write
"Top-level await not allowed" .js file extension Use .ts or .mjs
"Cannot find module 'node:fs'" Node compat needed Use Deno.* APIs instead
Slow startup Downloading remote modules Use vendor or deno cache
Type errors with npm packages Missing types Use @types or as any
Test failures Permissions in tests Add --allow-* to test command
Reference Documentation
-
Permissions
-
Standard Library
-
Testing
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: deno for comprehensive documentation.