.claude/skills/ts-deno-2/SKILL.md
Deno 2 — secure JavaScript/TypeScript runtime with npm compatibility. Use when building secure server-side apps, using TypeScript without config, deploying to Deno Deploy for serverless edge, or using npm packages inside Deno. Covers permissions model, npm imports, JSR registry, and built-in tooling (test, lint, fmt, compile).
npx skillsauth add eliferjunior/Claude deno-2Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Deno 2 is a secure JavaScript and TypeScript runtime built on V8. It is TypeScript-native, secure by default (explicit permissions required), and fully compatible with npm packages. Deno 2 adds backwards compatibility with Node.js APIs and package.json, making it a viable drop-in replacement for many Node.js projects.
# macOS / Linux
curl -fsSL https://deno.land/install.sh | sh
# Windows (PowerShell)
irm https://deno.land/install.ps1 | iex
# Homebrew
brew install deno
# Verify
deno --version
deno run main.ts # Run TypeScript directly
deno run --allow-net main.ts # With network permission
deno run --allow-all main.ts # All permissions (dev only)
deno run https://example.com/mod.ts # Run remote script
Deno is secure by default — all external access must be explicitly granted:
| Flag | Grants access to |
|---|---|
| --allow-net | Network (fetch, listen) |
| --allow-read | File system reads |
| --allow-write | File system writes |
| --allow-env | Environment variables |
| --allow-run | Subprocess execution |
| --allow-ffi | Native libraries |
| --allow-all or -A | Everything (avoid in prod) |
Fine-grained permissions:
deno run --allow-net=api.stripe.com --allow-read=./data main.ts
Use deno.json to set default permissions:
{
"tasks": {
"dev": "deno run --allow-net --allow-read --allow-env src/main.ts"
}
}
Deno runs TypeScript natively without tsconfig.json:
// main.ts — just works
interface User {
id: number;
name: string;
}
function greet(user: User): string {
return `Hello, ${user.name}!`;
}
const user: User = { id: 1, name: "Deno" };
console.log(greet(user));
Import npm packages directly with the npm: prefix:
import express from "npm:express";
import { z } from "npm:zod";
import axios from "npm:[email protected]";
const app = express();
app.get("/", (_req, res) => {
res.json({ message: "Hello from Deno + Express!" });
});
app.listen(3000, () => console.log("Server running on port 3000"));
Or declare in deno.json:
{
"imports": {
"express": "npm:express@^4",
"zod": "npm:zod@^3"
}
}
JSR is the modern package registry designed for Deno and TypeScript:
// Import from JSR
import { encodeBase64 } from "jsr:@std/encoding/base64";
import { Hono } from "jsr:@hono/hono";
// deno.json imports map
{
"imports": {
"@std/encoding": "jsr:@std/encoding@^1",
"@hono/hono": "jsr:@hono/hono@^4"
}
}
// Built-in Deno.serve — no imports needed
Deno.serve({ port: 3000 }, async (req: Request) => {
const url = new URL(req.url);
if (url.pathname === "/health") {
return Response.json({ status: "ok" });
}
if (req.method === "POST" && url.pathname === "/echo") {
const body = await req.json();
return Response.json(body);
}
return new Response("Not Found", { status: 404 });
});
console.log("Listening on http://localhost:3000");
// Read file
const text = await Deno.readTextFile("data.txt");
const bytes = await Deno.readFile("image.png");
// Write file
await Deno.writeTextFile("output.txt", "Hello, Deno!");
await Deno.writeFile("data.bin", new Uint8Array([1, 2, 3]));
// Read directory
for await (const entry of Deno.readDir(".")) {
console.log(entry.name, entry.isDirectory ? "dir" : "file");
}
// Stat
const stat = await Deno.stat("file.txt");
console.log(stat.size, stat.mtime);
// math_test.ts
import { assertEquals, assertThrows } from "jsr:@std/assert";
Deno.test("add works correctly", () => {
assertEquals(1 + 2, 3);
});
Deno.test("division by zero throws", () => {
assertThrows(() => {
if (0 === 0) throw new Error("Division by zero");
});
});
Deno.test({
name: "async fetch test",
permissions: { net: true },
async fn() {
const res = await fetch("https://httpbin.org/get");
assertEquals(res.status, 200);
},
});
deno test # Run all tests
deno test --watch # Watch mode
deno test --coverage=coverage/ # With coverage
deno test math_test.ts # Specific file
deno fmt # Format code (Prettier-compatible)
deno lint # Lint code
deno check main.ts # Type-check without running
deno doc main.ts # Generate documentation
deno compile main.ts # Compile to standalone binary
deno bundle main.ts # Bundle to single JS file (deprecated, use build)
deno info main.ts # Show module dependency tree
deno repl # Interactive REPL
{
"name": "my-app",
"version": "1.0.0",
"exports": "./mod.ts",
"tasks": {
"dev": "deno run --allow-net --allow-read --allow-env --watch src/main.ts",
"test": "deno test --allow-net",
"fmt": "deno fmt",
"lint": "deno lint",
"build": "deno compile --allow-net --allow-read src/main.ts"
},
"imports": {
"zod": "npm:zod@^3",
"@std/assert": "jsr:@std/assert@^1"
},
"lint": {
"rules": {
"include": ["no-unused-vars", "no-explicit-any"]
}
},
"fmt": {
"useTabs": false,
"lineWidth": 100
}
}
Deploy serverless edge functions globally:
// main.ts — deploy to Deno Deploy
Deno.serve((req) => {
const { pathname } = new URL(req.url);
if (pathname === "/") {
return new Response("Hello from the edge!", {
headers: { "Content-Type": "text/plain" },
});
}
return new Response("Not Found", { status: 404 });
});
# Install deployctl
deno install -A jsr:@deno/deployctl
# Deploy
deployctl deploy --project=my-project main.ts
// Access env vars (requires --allow-env)
const port = Deno.env.get("PORT") ?? "3000";
const apiKey = Deno.env.get("API_KEY");
if (!apiKey) {
throw new Error("API_KEY environment variable is required");
}
Load .env file:
import { load } from "jsr:@std/dotenv";
const env = await load();
const dbUrl = env.DATABASE_URL;
--allow-all in production.jsr:@std/* for standard library modules instead of deno.land/std.npm: prefix to import npm packages directly — no install step needed.deno.json imports map for cleaner code.deno fmt and deno lint as part of CI — they have zero config.deno compile to produce portable standalone executables.package.json — Node.js projects often work without changes.development
Expert guidance for Fireworks AI, the platform for running open-source LLMs (Llama, Mixtral, Qwen, etc.) with enterprise-grade speed and reliability. Helps developers integrate Fireworks' inference API, fine-tune models, and deploy custom model endpoints with function calling and structured output support.
development
Convert any website into clean, structured data with Firecrawl — API-first web scraping service. Use when someone asks to "turn a website into markdown", "scrape website for LLM", "Firecrawl", "extract website content as clean text", "crawl and convert to structured data", or "scrape website for RAG". Covers single-page scraping, full-site crawling, structured extraction, and LLM-ready output.
tools
Expert guidance for Firebase, Google's platform for building and scaling web and mobile applications. Helps developers set up authentication, Firestore/Realtime Database, Cloud Functions, hosting, storage, and analytics using Firebase's SDK and CLI.
development
When the user needs to build file upload functionality for a web application. Use when the user mentions "file upload," "image upload," "upload endpoint," "multipart upload," "presigned URL," "S3 upload," "file validation," "upload to cloud storage," or "accept user files." Handles upload endpoints, file validation (type, size, magic bytes), cloud storage integration, and upload status tracking. For image/video processing after upload, see media-transcoder.