Deno runtime for TypeScript/JavaScript. Covers permissions, standard library, testing, and Deploy. Use for secure, TypeScript-native backend development. USE WHEN: user mentions "deno", "permissions", "Deno.serve", asks about "deno test", "deno deploy", "standard library", "top-level await", "npm compatibility" DO NOT USE FOR: Node.js runtime - use `nodejs` skill instead DO NOT USE FOR: Fresh/Oak frameworks - use framework-specific skills DO NOT USE FOR: Language syntax - use `typescript` skill

GitHub
Install command
npx skhub add claude-dev-suite/deno
Markdown
SKILL.md

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

FlagDescription
--allow-readFile system read access
--allow-writeFile system write access
--allow-netNetwork access
--allow-envEnvironment variable access
--allow-runSubprocess execution
--allow-ffiForeign function interface
--allow-sysSystem information
-A or --allow-allAll 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

ScenarioUse Instead
Node.js runtime specificsnodejs skill
Fresh frameworkFramework-specific skill
Oak frameworkFramework-specific skill
TypeScript syntaxtypescript skill
npm package ecosystemnodejs skill

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Using --allow-allDefeats security modelGrant specific permissions
Not versioning importsBreaking changesPin versions in imports
Ignoring lock fileReproducibility issuesCommit deno.lock
Mixing npm: and https: importsInconsistent depsPrefer one approach
Not handling permission errorsRuntime failuresCheck permissions first
Synchronous file I/OBlocks runtimeUse async Deno APIs
No error boundariesUnhandled errorsAdd error middleware
Hardcoded URLsPortability issuesUse environment variables

Quick Troubleshooting

IssueCauseSolution
"PermissionDenied"Missing permission flagAdd --allow-* flag
"Module not found"Wrong URL or versionCheck import URL
"Integrity check failed"Lock file mismatchRun with --lock-write
"Top-level await not allowed".js file extensionUse .ts or .mjs
"Cannot find module 'node:fs'"Node compat neededUse Deno.* APIs instead
Slow startupDownloading remote modulesUse vendor or deno cache
Type errors with npm packagesMissing typesUse @types or as any
Test failuresPermissions in testsAdd --allow-* to test command

Reference Documentation

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: deno for comprehensive documentation.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/languages/deno

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1