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.
development
Debug HTTP APIs: trace requests, inspect headers. Use when a request fails: check status first.
documentation
Render architecture diagrams from text sources. Use when documenting system topology.
tools
Inspect JSON payloads and extract nested fields. Use when parsing API responses.
tools
--- name: no-description allowed-tools: Read --- # No Description This skill has no description and must be dropped with a warning.