| name | Deno TypeScript LSP |
| description | Use this skill when working with TypeScript/JavaScript files (.ts, .tsx, .js, .jsx, .mts, .cts, .mjs, .cjs) in Deno projects, or when the user asks about Deno-specific patterns, imports, configuration, testing, or tooling. |
| version | 1.0.0 |
Deno TypeScript Development
Deno is the primary TypeScript/JavaScript runtime and language server. It replaces the entire Node.js toolchain: no tsc, eslint, prettier, jest, webpack needed.
Core Philosophy
- One tool - Deno handles typecheck, lint, format, test, coverage, benchmark
- Security first - Explicit permissions, minimal external dependencies
- Import maps - All dependencies declared in
deno.json, never direct imports
- ESM only - No CommonJS, always include
.ts extensions in relative imports
Configuration - deno.json
Single source of truth for all project configuration:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"imports": {
"@/": "./src/",
"@std/assert": "jsr:@std/assert@^1.0.14",
"@std/fs": "jsr:@std/fs@^1.0.19",
"zod": "npm:zod@^3.23.8"
},
"tasks": {
"dev": "deno run --watch --allow-net --allow-read src/main.ts",
"test": "deno test --allow-all --coverage=coverage",
"check": "deno check src/**/*.ts",
"lint": "deno lint",
"fmt": "deno fmt"
},
"exclude": ["coverage/", "node_modules/"],
"lock": true
}
Import Strategy
CRITICAL: Never use direct JSR/npm imports in source files.
import { assertEquals } from "@std/assert";
import { z } from "zod";
import { Agent } from "@/domain/agent.ts";
import { helper } from "./utils.ts";
import { z } from "npm:zod@^3.23.8";
import { assertEquals } from "jsr:@std/assert";
Import Order:
- Standard library (
@std/*)
- Third-party (
zod, etc.)
- Internal absolute (
@/domain/...)
- Relative (
./utils.ts)
Version Pinning: Always pin versions in deno.json. No floating @latest.
Dependency Sources (Priority Order)
jsr: registry - First choice for TypeScript modules
npm: specifier - When JSR unavailable, prefer ESM-compatible
- URL imports - Rarely needed with import maps
{
"imports": {
"@std/assert": "jsr:@std/assert@^1.0.14",
"zod": "npm:zod@^3.23.8"
}
}
Testing
Co-locate unit tests with source:
src/
└── domain/
├── agent.ts
└── agent.test.ts # Test file next to source
Test file naming: Always use .test.ts suffix.
AAA Pattern (Arrange-Act-Assert):
import { assertEquals } from "@std/assert";
Deno.test("agent processes valid input", () => {
const agent = new Agent({ name: "Test" });
const result = agent.process("hello");
assertEquals(result.status, "success");
});
Coverage requirements:
- Line coverage: 80%+ (non-negotiable)
- Branch coverage: 60-80% (non-negotiable)
Use @std/testing for test utilities:
import { FakeTime } from "@std/testing/time";
import { stub, spy } from "@std/testing/mock";
Deno.test("timer behavior", () => {
using time = new FakeTime();
time.tick(1000);
});
Permissions Model
Default to minimum required permissions:
deno run --allow-all script.ts
deno run --allow-read=./data --allow-net=api.example.com script.ts
Common flags:
--allow-read[=<path>] - File system read
--allow-write[=<path>] - File system write
--allow-net[=<domain>] - Network access
--allow-env[=<var>] - Environment variables
--allow-run[=<program>] - Subprocess execution
Essential Commands
deno run --watch src/main.ts
deno check src/**/*.ts
deno fmt
deno lint
deno test
deno test --watch --fail-fast
deno test --coverage=coverage
deno coverage coverage --html
deno add jsr:@std/path
deno cache --reload
deno cache --lock=deno.lock --lock-write
deno task dev
Standard Library (@std/*)
Use JSR standard library for common utilities:
@std/assert - Testing assertions
@std/fs - File system utilities
@std/path - Path manipulation
@std/http - HTTP server/client
@std/async - Async utilities (debounce, retry, etc.)
@std/testing - Mock, spy, FakeTime
@std/ulid - ULID generation
Anti-Patterns to Avoid
import { z } from "npm:zod@^3.23.8";
import { helper } from "./utils";
import * as fs from "node:fs";
const fs = require("fs");
async function validate(input: string): Promise<boolean> {
return input.length > 0;
}
await new Promise(r => setTimeout(r, 100));
Lockfile Management
- Always commit
deno.lock to version control
- Update lockfile:
deno cache --lock=deno.lock --lock-write
- CI mode:
deno run --lock=deno.lock --lock-write=false