typescript-plugin/skills/typescript-debugging/SKILL.md
Modern TypeScript/JavaScript debugging with Bun — inspector flags, debug.bun.sh, VSCode launch.json, memory profiling, heap analysis. Use when setting up interactive debugging, investigating leaks, CPU profiling with `--cpu-prof`, or sourcemaps.
npx skillsauth add laurigates/claude-plugins typescript-debuggingInstall 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.
| Scenario | Use this skill | Alternative |
|----------|---------------|-------------|
| Setting up Bun inspector for debugging | Yes | N/A |
| Configuring VSCode launch.json for Bun | Yes | N/A |
| Investigating memory leaks with heap snapshots | Yes | N/A |
| CPU profiling TypeScript applications | Yes | N/A |
| Debugging network requests with verbose fetch | Yes | N/A |
| Setting up sourcemaps for debugging | Yes | bun-development for build-time sourcemap flags |
| Monitoring errors in production | No - use typescript-sentry | N/A |
| Running tests to find failures | No - use bun-development | bun-test for quick test runs |
Modern debugging for TypeScript/JavaScript with Bun runtime:
# Start with debugger enabled
bun --inspect script.ts
# Custom port
bun --inspect=4000 script.ts
# Custom host:port
bun --inspect=localhost:4000 script.ts
# Break at first line (for fast scripts)
bun --inspect-brk script.ts
# Wait for debugger before running
bun --inspect-wait script.ts
# Debug test file
bun --inspect test
# Break before tests run
bun --inspect-brk test auth.test.ts
Bun's built-in web debugger is a modified WebKit Web Inspector:
# Start debugging - outputs debug URL
bun --inspect script.ts
# ------------------- Bun Inspector -------------------
# Listening: ws://localhost:6499/
# Open: debug.bun.sh/#localhost:6499
# -----------------------------------------------------
| Feature | Description | |---------|-------------| | Source view | View original TypeScript/JSX with sourcemaps | | Breakpoints | Click line numbers to set/remove | | Console | Execute code in current context | | Call stack | Inspect execution frames | | Scope | View local/closure/global variables | | Watch | Add expressions to monitor |
| Control | Action | |---------|--------| | Continue (F8) | Run until next breakpoint | | Step Over (F10) | Execute line, skip into functions | | Step Into (F11) | Enter function call | | Step Out (Shift+F11) | Complete function, return to caller |
Install Bun for Visual Studio Code.
{
"version": "0.2.0",
"configurations": [
{
"type": "bun",
"request": "launch",
"name": "Debug Script",
"program": "${workspaceFolder}/src/index.ts",
"cwd": "${workspaceFolder}",
"stopOnEntry": false,
"watchMode": false
},
{
"type": "bun",
"request": "launch",
"name": "Debug Tests",
"program": "${workspaceFolder}/tests/index.test.ts",
"cwd": "${workspaceFolder}",
"runtime": "bun",
"runtimeArgs": ["test"]
},
{
"type": "bun",
"request": "launch",
"name": "Debug with Watch",
"program": "${workspaceFolder}/src/index.ts",
"watchMode": true
},
{
"type": "bun",
"request": "attach",
"name": "Attach to Bun",
"url": "ws://localhost:6499/"
}
]
}
| Option | Type | Description |
|--------|------|-------------|
| program | string | Entry file path |
| cwd | string | Working directory |
| args | string[] | Arguments to script |
| env | object | Environment variables |
| stopOnEntry | boolean | Break at first line |
| watchMode | boolean | Enable --watch/--hot |
| noDebug | boolean | Run without debugger |
| strictEnv | boolean | Only use specified env |
Create snapshots for Chrome DevTools analysis:
import { writeHeapSnapshot } from "v8";
// Create snapshot at any point
writeHeapSnapshot("before.heapsnapshot");
// After suspect operation
doSomeWork();
writeHeapSnapshot("after.heapsnapshot");
Load .heapsnapshot files in Chrome DevTools Memory tab for comparison.
import { heapStats } from "bun:jsc";
const stats = heapStats();
console.log({
heapSize: stats.heapSize,
objectCount: stats.objectCount,
objectTypeCounts: stats.objectTypeCounts
});
// objectTypeCounts: { Array: 1234, Object: 5678, Function: 890, ... }
// Resident Set Size (actual RAM used)
console.log(process.memoryUsage.rss());
// Full memory breakdown
console.log(process.memoryUsage());
// { rss, heapTotal, heapUsed, external, arrayBuffers }
# Show native memory stats
MIMALLOC_SHOW_STATS=1 bun script.ts
# Generate CPU profile
bun --cpu-prof script.ts
# Produces .cpuprofile file for Chrome DevTools
# Log all fetch/http requests
BUN_CONFIG_VERBOSE_FETCH=1 bun script.ts
# Log as curl commands
BUN_CONFIG_VERBOSE_FETCH=curl bun script.ts
Bun automatically generates sourcemaps for transpiled files:
# External sourcemaps (recommended for debugging)
bun build ./src/index.ts --outdir=dist --sourcemap=external
# Inline sourcemaps
bun build ./src/index.ts --outdir=dist --sourcemap=inline
# No sourcemaps (production)
bun build ./src/index.ts --outdir=dist --sourcemap=none
// Structured object/array display
console.table([{ id: 1, name: "a" }, { id: 2, name: "b" }]);
// Timing operations
console.time("fetch");
await fetch(url);
console.timeEnd("fetch"); // fetch: 234ms
// Group related logs
console.group("Request");
console.log("URL:", url);
console.log("Method:", method);
console.groupEnd();
// Conditional logging
console.assert(value > 0, "Value must be positive", value);
// Stack trace without error
console.trace("Reached here");
// Pause execution when debugger attached
debugger;
// Conditional breakpoint
if (suspiciousCondition) {
debugger;
}
// BAD: largeData retained in closure
const largeData = loadHugeArray();
setInterval(() => {
console.log(largeData.length); // Keeps largeData alive forever
}, 1000);
// GOOD: Copy only needed data
const dataLength = largeData.length;
setInterval(() => {
console.log(dataLength);
}, 1000);
// BAD: Listener never removed
emitter.on("data", handler);
// GOOD: Use once for single events
emitter.once("data", handler);
// GOOD: Explicit cleanup
emitter.on("data", handler);
// Later...
emitter.removeListener("data", handler);
// For long-running operations
const controller = new AbortController();
const response = await fetch(url, { signal: controller.signal });
// Cleanup on timeout
setTimeout(() => controller.abort(), 30000);
// BAD: Grows indefinitely
const cache: Map<string, Data> = new Map();
export function getData(key: string) {
if (!cache.has(key)) {
cache.set(key, expensiveCompute(key));
}
return cache.get(key);
}
// GOOD: Use LRU or TTL cache
import { LRUCache } from "lru-cache";
const cache = new LRUCache<string, Data>({ max: 1000 });
--cpu-prof.cpuprofile in Chrome DevTools| Context | Command |
|---------|---------|
| Quick debug | bun --inspect-brk script.ts |
| Debug tests | bun --inspect-brk test |
| Memory check | bun -e "import{heapStats}from'bun:jsc';console.log(heapStats())" |
| Network debug | BUN_CONFIG_VERBOSE_FETCH=curl bun script.ts |
| CPU profile | bun --cpu-prof script.ts |
| Native memory | MIMALLOC_SHOW_STATS=1 bun script.ts |
| Flag | Description |
|------|-------------|
| --inspect | Enable debugger on available port |
| --inspect=<port> | Enable debugger on specific port |
| --inspect-brk | Break at first line |
| --inspect-wait | Wait for debugger attachment |
| --cpu-prof | Generate CPU profile |
| URL | Purpose |
|-----|---------|
| debug.bun.sh | Bun's web debugger |
| chrome://inspect | Chrome DevTools (for heap analysis) |
| Variable | Description |
|----------|-------------|
| BUN_CONFIG_VERBOSE_FETCH | 1 or curl for request logging |
| MIMALLOC_SHOW_STATS | 1 to show native memory stats |
| API | Import | Purpose |
|-----|--------|---------|
| writeHeapSnapshot() | v8 | Create heap snapshot file |
| heapStats() | bun:jsc | Get heap statistics |
| memoryUsage() | process | Get process memory |
| memoryUsage.rss() | process | Get resident set size |
# Check if port is in use
lsof -i :6499
# Try explicit port
bun --inspect=9229 script.ts
--inspect-brk for fast-exiting scriptsBun's Unix socket debugging may not work on Windows. Use WSL or the web debugger instead.
testing
Verify accumulated bug claims at upstream HEAD and dedup against trackers before filing issues. Use when filing upstream reports from backlogs, audit docs, or git-history findings.
documentation
Gate outward-bound text (upstream issues, docs, PR bodies) through isolated haiku fresh-reader critique before publishing. Use when an artifact must survive a reader with zero project context.
tools
Suggest improvements to SKILL.md content, descriptions, or tool config from eval results. Use when raising pass rates, fixing triggering, or iterating on a skill after evaluation.
tools
deadbranch CLI for stale-branch cleanup — dry-run preview, TUI or non-interactive delete, protects main/develop/WIP. Use when asked to clean up branches, prune branches, or remove stale branches.