`n

VS Code Debugging Configuration - Complete Guide

Published: September 25, 2024 | Reading time: 15 minutes

Quick Debug Setup

Get debugging working in VS Code with these essential configurations:

Debug Shortcuts
F5 - Start debugging
F9 - Toggle breakpoint
F10 - Step over
F11 - Step into
Shift+F11 - Step out
Ctrl+Shift+F5 - Restart debugging
Shift+F5 - Stop debugging

Understanding VS Code Debugging

VS Code's debugging capabilities are built on the Debug Adapter Protocol (DAP), which provides:

  • Multi-language support - Debug JavaScript, Python, C++, Go, and more
  • Breakpoint management - Set conditional and logpoint breakpoints
  • Variable inspection - Examine variables and expressions in real-time
  • Call stack navigation - Step through execution flow
  • Watch expressions - Monitor specific variables or expressions

JavaScript/Node.js Debugging

Basic Node.js Configuration

launch.json - Node.js
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Node.js",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/app.js",
      "console": "integratedTerminal",
      "env": {
        "NODE_ENV": "development"
      },
      "skipFiles": [
        "/**"
      ]
    }
  ]
}

Express.js Debugging

Express Debug Configuration
{
  "name": "Launch Express App",
  "type": "node",
  "request": "launch",
  "program": "${workspaceFolder}/server.js",
  "env": {
    "NODE_ENV": "development",
    "PORT": "3000"
  },
  "console": "integratedTerminal",
  "restart": true,
  "runtimeExecutable": "nodemon",
  "runtimeArgs": ["--inspect"]
}

Browser Debugging

Chrome Debug Configuration
{
  "name": "Launch Chrome",
  "type": "chrome",
  "request": "launch",
  "url": "http://localhost:3000",
  "webRoot": "${workspaceFolder}/src",
  "sourceMaps": true,
  "userDataDir": false,
  "runtimeArgs": [
    "--disable-web-security",
    "--disable-features=VizDisplayCompositor"
  ]
}

Python Debugging

Basic Python Configuration

Python Debug Setup
{
  "name": "Python: Current File",
  "type": "python",
  "request": "launch",
  "program": "${file}",
  "console": "integratedTerminal",
  "justMyCode": true,
  "env": {
    "PYTHONPATH": "${workspaceFolder}"
  }
}

Django Debugging

Django Debug Configuration
{
  "name": "Django: Debug",
  "type": "python",
  "request": "launch",
  "program": "${workspaceFolder}/manage.py",
  "args": ["runserver", "0.0.0.0:8000"],
  "django": true,
  "justMyCode": true,
  "env": {
    "DJANGO_SETTINGS_MODULE": "myproject.settings"
  }
}

Flask Debugging

Flask Debug Configuration
{
  "name": "Flask: Debug",
  "type": "python",
  "request": "launch",
  "program": "${workspaceFolder}/app.py",
  "env": {
    "FLASK_APP": "app.py",
    "FLASK_ENV": "development",
    "FLASK_DEBUG": "1"
  },
  "console": "integratedTerminal"
}

Advanced Debugging Features

Conditional Breakpoints

Set breakpoints that only trigger under specific conditions:

Conditional Breakpoint Example
// JavaScript example
function processUsers(users) {
  for (let user of users) {
    // Breakpoint condition: user.age > 18
    console.log(user.name); // Set conditional breakpoint here
  }
}

# Python example
def process_data(items):
    for item in items:
        # Breakpoint condition: item['status'] == 'error'
        print(item['name'])  # Set conditional breakpoint here

Logpoints

Add logging without modifying your code:

Logpoint Examples
// JavaScript logpoint
User ID: {user.id}, Status: {user.status}

# Python logpoint
Processing item: {item['name']}, Count: {len(items)}

Watch Expressions

Monitor variables and expressions during debugging:

Watch Examples
// JavaScript watch expressions
user.name.length
Object.keys(user).length
user.age > 18 ? 'adult' : 'minor'

# Python watch expressions
len(user_list)
user['age'] if user else None
sum(item['price'] for item in items)

Multi-target Debugging

Compound Configurations

Debug multiple processes simultaneously:

Compound Configuration
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Backend",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/backend/server.js"
    },
    {
      "name": "Launch Frontend",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000"
    }
  ],
  "compounds": [
    {
      "name": "Launch Full Stack",
      "configurations": ["Launch Backend", "Launch Frontend"],
      "stopAll": true
    }
  ]
}

Debugging Extensions

Essential Debug Extensions

Language Specific

  • Python Debugger
  • C/C++ Extension Pack
  • Go for Visual Studio Code
  • Rust Analyzer
  • PHP Debug

Framework Specific

  • Debugger for Chrome
  • Firefox Debug Adapter
  • Edge Debugger
  • Docker Extension
  • Remote Development

Remote Debugging

Docker Container Debugging

Docker Debug Configuration
{
  "name": "Docker: Attach to Node",
  "type": "node",
  "request": "attach",
  "port": 9229,
  "restart": true,
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "/app",
  "protocol": "inspector"
}

Remote Server Debugging

Remote Debug Setup
# On remote server
node --inspect=0.0.0.0:9229 app.js

# VS Code configuration
{
  "name": "Remote Debug",
  "type": "node",
  "request": "attach",
  "address": "your-server-ip",
  "port": 9229,
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "/path/to/remote/app"
}

Debugging Best Practices

Performance Tips

  • Use skipFiles - Skip node_modules and other irrelevant files
  • Set justMyCode - Only debug your own code in Python
  • Use conditional breakpoints - Avoid unnecessary stops
  • Limit watch expressions - Too many can slow down debugging
  • Use logpoints - Less intrusive than console.log statements

Debugging Workflow

Effective Debugging Steps
1. Reproduce the issue consistently
2. Set breakpoints at key points
3. Use step-through debugging
4. Inspect variables and state
5. Use watch expressions for complex logic
6. Test fixes incrementally
7. Remove debug code before committing

Common Debugging Scenarios

Async/Await Debugging

Async Debugging Tips
// JavaScript async debugging
async function fetchUserData(userId) {
  try {
    // Set breakpoint here to inspect userId
    const user = await fetch(`/api/users/${userId}`);
    // Set breakpoint here to inspect response
    const data = await user.json();
    return data;
  } catch (error) {
    // Set breakpoint here for error handling
    console.error('Error fetching user:', error);
    throw error;
  }
}

Promise Chain Debugging

Promise Debugging
// Set breakpoints at each .then() to trace execution
fetch('/api/data')
  .then(response => {
    // Breakpoint 1: Check response status
    return response.json();
  })
  .then(data => {
    // Breakpoint 2: Inspect parsed data
    return processData(data);
  })
  .catch(error => {
    // Breakpoint 3: Handle errors
    console.error('Error:', error);
  });

Summary

Mastering VS Code debugging involves:

  • Understanding debug configurations for your language/framework
  • Using advanced features like conditional breakpoints and logpoints
  • Setting up remote and multi-target debugging
  • Following best practices for performance and workflow
  • Using appropriate extensions for your tech stack

Need More Help?

Struggling with debugging setup or need help with specific debugging scenarios? Our debugging experts can help you master VS Code's debugging capabilities.

Get Debugging Help