Back to Skills

deno-patterns

verified

Modern TypeScript patterns and migration guidance for Deno: resource management with 'using', async generators, error handling, and Web Standard APIs. Use when migrating from Node.js, implementing cleanup logic, or learning modern JS/TS patterns.

View on GitHub

Marketplace

local-plugins

jahanson/cc-plugins

Plugin

deno-lsp

Repository

jahanson/cc-plugins

deno-lsp/skills/deno-patterns/SKILL.md

Last Verified

January 21, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/jahanson/cc-plugins/blob/main/deno-lsp/skills/deno-patterns/SKILL.md -a claude-code --skill deno-patterns

Installation paths:

Claude
.claude/skills/deno-patterns/
Powered by add-skill CLI

Instructions

# Deno Modern Patterns & Migration

## When to Use This Skill

Use this skill when:
- Migrating from Node.js to Deno
- Learning modern JavaScript/TypeScript patterns
- Implementing resource management
- Working with timers, polling, or cleanup logic
- Handling errors in Deno
- Choosing between old and new patterns

**Note:** Always read `deno-core.md` first for essential configuration and practices.

---

## Resource Management with `using`

### The Problem with Manual Cleanup

**Old Pattern:**

```javascript
// Manual timer cleanup - error-prone
const id = setInterval(() => {
  console.log("Tick!");
}, 1000);

// Later, cleanup (easy to forget!)
clearInterval(id);
```

**Problems:**
- Resource leaks if cleanup is missed
- Not exception-safe
- Resource not tied to lexical scope
- Cleanup code separated from acquisition

### The `using` Statement (Deno >= v2.4)

**New Pattern:**

```typescript
// Automatic, exception-safe cleanup
class Timer {
  #handle: number;

  constructor(cb: () => void, ms: number) {
    this.#handle = setInterval(cb, ms);
  }

  [Symbol.dispose]() {
    clearInterval(this.#handle);
    console.log("Timer disposed");
  }
}

using timer = new Timer(() => {
  console.log("Tick!");
}, 1000);
// Timer automatically cleaned up at end of scope
```

**Benefits:**
- Automatic cleanup at scope exit
- Exception-safe (cleanup happens even if errors occur)
- Follows RAII (Resource Acquisition Is Initialization) principles
- Prevents resource leaks in complex control flows
- Composable with multiple `using` declarations

### Async Resource Management

For async cleanup, use `await using` with `Symbol.asyncDispose`:

```typescript
class DatabaseConnection {
  #conn: Connection;

  constructor(conn: Connection) {
    this.#conn = conn;
  }

  async [Symbol.asyncDispose]() {
    await this.#conn.close();
    console.log("Database connection closed");
  }
}

// Automatically closes when scope exits
await using db = new DatabaseConnection(conn);
await db.query("

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
13862 chars