typescript-debugging

v2026.09.24

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.

GitHub
Install command
npx skhub add laurigates/typescript-debugging
Markdown
SKILL.md

TypeScript Debugging

When to Use This Skill

ScenarioUse this skillAlternative
Setting up Bun inspector for debuggingYesN/A
Configuring VSCode launch.json for BunYesN/A
Investigating memory leaks with heap snapshotsYesN/A
CPU profiling TypeScript applicationsYesN/A
Debugging network requests with verbose fetchYesN/A
Setting up sourcemaps for debuggingYesbun-development for build-time sourcemap flags
Monitoring errors in productionNo - use typescript-sentryN/A
Running tests to find failuresNo - use bun-developmentbun-test for quick test runs

Core Expertise

Modern debugging for TypeScript/JavaScript with Bun runtime:

  • WebKit Inspector Protocol (debug.bun.sh)
  • VSCode integration with Bun extension
  • Memory profiling with V8 heap snapshots
  • Automatic sourcemap generation for TypeScript
  • Chrome DevTools for heap analysis

Inspector Flags

Basic Debugging

# 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 on Start

# Break at first line (for fast scripts)
bun --inspect-brk script.ts

# Wait for debugger before running
bun --inspect-wait script.ts

Debugging Tests

# Debug test file
bun --inspect test

# Break before tests run
bun --inspect-brk test auth.test.ts

Web Debugger (debug.bun.sh)

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
# -----------------------------------------------------

Features

FeatureDescription
Source viewView original TypeScript/JSX with sourcemaps
BreakpointsClick line numbers to set/remove
ConsoleExecute code in current context
Call stackInspect execution frames
ScopeView local/closure/global variables
WatchAdd expressions to monitor

Execution Controls

ControlAction
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

VSCode Integration

Extension Setup

Install Bun for Visual Studio Code.

launch.json Configuration

{
  "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/"
    }
  ]
}

Configuration Options

OptionTypeDescription
programstringEntry file path
cwdstringWorking directory
argsstring[]Arguments to script
envobjectEnvironment variables
stopOnEntrybooleanBreak at first line
watchModebooleanEnable --watch/--hot
noDebugbooleanRun without debugger
strictEnvbooleanOnly use specified env

Memory Debugging

Heap Snapshots

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.

Heap Statistics (bun:jsc)

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, ... }

Process Memory

// Resident Set Size (actual RAM used)
console.log(process.memoryUsage.rss());

// Full memory breakdown
console.log(process.memoryUsage());
// { rss, heapTotal, heapUsed, external, arrayBuffers }

Non-JS Memory (mimalloc)

# Show native memory stats
MIMALLOC_SHOW_STATS=1 bun script.ts

Performance Profiling

CPU Profiling

# Generate CPU profile
bun --cpu-prof script.ts

# Produces .cpuprofile file for Chrome DevTools

Network Request Debugging

# 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

Sourcemaps

Bun automatically generates sourcemaps for transpiled files:

  • TypeScript → JavaScript mapping preserved
  • JSX transformations tracked
  • Stack traces show original source locations
  • Debugger shows TypeScript, not transpiled JS

Build with Sourcemaps

# 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

Console Debugging

Beyond console.log

// 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");

Programmatic Breakpoints

// Pause execution when debugger attached
debugger;

// Conditional breakpoint
if (suspiciousCondition) {
  debugger;
}

Common Leak Patterns

Closure Entrapment

// 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);

Event Listener Cleanup

// 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);

AbortSignal/AbortController

// For long-running operations
const controller = new AbortController();
const response = await fetch(url, { signal: controller.signal });

// Cleanup on timeout
setTimeout(() => controller.abort(), 30000);

Module-Level Variables

// 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 });

Debugging Workflow

Memory Leak Investigation

  1. Baseline: Create heap snapshot at startup
  2. Reproduce: Perform suspect operations
  3. Compare: Create second snapshot, compare in DevTools
  4. Identify: Look for growing object counts (Delta column)
  5. Trace: Use retainers view to find what's holding references

Performance Investigation

  1. Profile: Run with --cpu-prof
  2. Load: Open .cpuprofile in Chrome DevTools
  3. Analyze: Check flame graph for hot paths
  4. Optimize: Focus on widest flames first

Agentic Optimizations

ContextCommand
Quick debugbun --inspect-brk script.ts
Debug testsbun --inspect-brk test
Memory checkbun -e "import{heapStats}from'bun:jsc';console.log(heapStats())"
Network debugBUN_CONFIG_VERBOSE_FETCH=curl bun script.ts
CPU profilebun --cpu-prof script.ts
Native memoryMIMALLOC_SHOW_STATS=1 bun script.ts

Quick Reference

Inspector Flags

FlagDescription
--inspectEnable debugger on available port
--inspect=<port>Enable debugger on specific port
--inspect-brkBreak at first line
--inspect-waitWait for debugger attachment
--cpu-profGenerate CPU profile

Debug URLs

URLPurpose
debug.bun.shBun's web debugger
chrome://inspectChrome DevTools (for heap analysis)

Environment Variables

VariableDescription
BUN_CONFIG_VERBOSE_FETCH1 or curl for request logging
MIMALLOC_SHOW_STATS1 to show native memory stats

Memory APIs

APIImportPurpose
writeHeapSnapshot()v8Create heap snapshot file
heapStats()bun:jscGet heap statistics
memoryUsage()processGet process memory
memoryUsage.rss()processGet resident set size

Troubleshooting

Debugger Not Connecting

# Check if port is in use
lsof -i :6499

# Try explicit port
bun --inspect=9229 script.ts

Breakpoints Not Hit

  • Ensure sourcemaps are enabled
  • Use --inspect-brk for fast-exiting scripts
  • Check file paths match in debugger

VSCode Issues (Windows)

Bun's Unix socket debugging may not work on Windows. Use WSL or the web debugger instead.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

typescript-plugin/skills/typescript-debugging

Default branch

main

Latest commit

1668324

Tree SHA

b2d4cc3