SuperAPI AI Directory

deno

Coding & development

View repository

Updated 10-15 18:51

About this skill

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

```typescript
// 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

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