Skip to content

VS Code Deep Dive — Extensions, Settings, Debugging & Remote Dev

DodaTech Updated 2026-06-22 6 min read

VS Code is a lightweight but powerful code editor that becomes an IDE through extensions, settings, and integrated tools for debugging, remote development, and task automation.

What You'll Learn

In this tutorial, you'll learn VS Code extensions for every language, settings.json optimization, launch.json debugging configurations, Remote-SSH and Dev Containers, Tasks runner, user snippets, and workspace-level customization for team consistency.

Why It Matters

Most developers use less than 20% of VS Code's capabilities. Mastering the remaining 80% eliminates context switching — you debug in-editor, run tasks without leaving the terminal, and connect to remote servers seamlessly. This saves 5-10 hours per week.

Real-World Use

DodaZIP's development team uses a shared .vscode/settings.json and extension recommendations file to ensure every developer has the same linting, formatting, and debugging setup. Remote-SSH connects to the build server directly from the editor.

flowchart LR
  A[VS Code] --> B[Extensions]
  A --> C[Settings.json]
  A --> D[Debugger]
  A --> E[Remote Dev]
  B --> F[Language Support]
  B --> G[Linters + Formatters]
  B --> H[Productivity]
  D --> I[Node.js Debug]
  D --> J[Python Debug]
  D --> K[C++ GDB]
  E --> L[Remote-SSH]
  E --> M[Dev Containers]
  E --> N[WSL]

Essential Extensions

Extension recommendations belong in .vscode/extensions.json so the team stays in sync.

{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "github.copilot",
    "ms-vscode-remote.remote-ssh",
    "ms-azuretools.vscode-docker]
  ]
}

Expected behavior: When a developer opens the workspace, VS Code prompts them to install the recommended extensions.

Top Extensions by Category

Category Extensions Purpose
Language Support Python, JavaScript/TypeScript, Go, Rust, C++ Syntax highlighting, IntelliSense, debugging
Linting & Formatting ESLint, Prettier, Black, Ruff Auto-format on save, lint-on-type
Productivity GitHub Copilot, GitLens, Todo Tree, Path Intellisense AI completion, git blame, TODO tracking
Remote Dev Remote-SSH, Dev Containers, WSL Edit remote files, container-based development
Visual Material Icon Theme, Bracket Pair Colorizer (built-in), Peacock Color-coded brackets, project tinting

Settings and Configuration

settings.json

{
  "editor.fontSize": 14,
  "editor.fontFamily": "'Cascadia Code', 'Fira Code', 'JetBrains Mono', monospace",
  "editor.fontLigatures": true,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.minimap.enabled": false,
  "editor.renderWhitespace": "boundary",
  "editor.bracketPairColorization.enabled": true,
  "editor.guides.bracketPairs": true,
  "workbench.colorTheme": "One Dark Pro",
  "files.autoSave": "onFocusChange",
  "terminal.integrated.fontSize": 13
}

Expected behavior: Code auto-formats on every save. Brackets are color-matched with vertical guides. The minimap is hidden (reclaim screen space). Auto-save triggers when you switch tabs.

Per-Language Settings

{
  "[python]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "ms-python.black-formatter",
    "editor.codeActionsOnSave": {
      "source.organizeImports": "explicit"
    }
  },
  "[rust]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "rust-lang.rust-analyzer"
  }
}

Expected behavior: Python files format with Black on save and auto-organize imports. Rust files format with rust-analyzer. Other languages use the default Prettier.

Integrated Debugging

Node.js Debug Configuration

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceFolder}/src/index.js",
      "env": { "NODE_ENV": "development" },
      "skipFiles": ["<node_internals>/**"]
    },
    {
      "type": "node",
      "request": "attach",
      "name": "Attach to Process",
      "port": 9229,
      "restart": true
    }
  ]
}

Expected behavior: Press F5 to start the program with the debugger attached. Breakpoints pause execution. Variables, call stack, and watch expressions are visible in the Debug pane.

Conditional Breakpoints

Right-click the gutter next to a line number, select "Add Conditional Breakpoint", and enter an expression:

function processFile(file) {
  // Conditional breakpoint: file.name.includes('malware')
  console.log(`Processing ${file.name}`);
}

Expected behavior: The debugger pauses only when the condition evaluates to true. This is invaluable for isolating a specific file or state in a loop.

Remote Development

Remote-SSH

# From VS Code command palette: Remote-SSH: Connect to Host
# Configure ~/.ssh/config for quick access
Host build-server
  HostName 192.168.1.100
  User developer
  IdentityFile ~/.ssh/id_ed25519

Expected behavior: VS Code opens a new window connected to the remote server. The file explorer, terminal, and debugger all operate over SSH. Extensions run locally; language servers run remotely.

Dev Containers

# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm
RUN apt-get update && apt-get install -y netcat-openbsd

Expected behavior: VS Code detects the .devcontainer folder and prompts "Reopen in Container". The editor runs inside a Docker container with Node.js 20, all extensions, and project dependencies pre-installed.

Tasks — Automate Repetitive Work

// .vscode/tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Build",
      "type": "npm",
      "script": "build",
      "group": { "kind": "build", "isDefault": true },
      "problemMatcher": ["$tsc"]
    },
    {
      "label": "Run Tests",
      "type": "npm",
      "script": "test",
      "group": { "kind": "test", "isDefault": true }
    }
  ]
}

Expected behavior: Ctrl+Shift+B runs the build task. Errors appear in the Problems panel with file links. Test output shows in the terminal panel.

Common Errors

  1. Not using a workspace file — Opening a single folder loses project-specific settings. Use File > Save Workspace As to create a .code-workspace file that remembers open files and settings.
  2. Global settings override per-project settings — Your user settings.json applies everywhere. Use .vscode/settings.json in each project for team-consistent settings.
  3. Missing launch.json for debugging — Without a launch configuration, F5 might not start correctly. Use the Run panel's "create a launch.json file" link to auto-generate one.
  4. Extensions slowing down startup — Disable extensions you don't use daily. Run Developer: Show Running Extensions to see startup time impact.
  5. Remote-SSH key issues — If Remote-SSH keeps asking for a password, ensure your public key is in ~/.ssh/authorized_keys on the remote machine and the private key is added to ssh-agent.

Practice Questions

  1. How do you ensure consistent settings across a team? Add .vscode/settings.json and .vscode/extensions.json to the repository. These override user settings for the workspace.

  2. What is the difference between launch and attach debug configurations? launch starts the program from VS Code; attach connects to an already-running process (usually with --inspect flag).

  3. How can you edit files on a remote server without terminal-based editors? Use the Remote-SSH extension. Open VS Code, run Remote-SSH: Connect to Host, and edit files through the editor interface.

  4. What does editor.formatOnSave do and why is it useful? It auto-formats the file using the default formatter whenever you save. This eliminates manual formatting and enforces consistent style.

Challenge

Create a .vscode folder for a project that includes: a tasks.json with build and test tasks, a launch.json for debugging with environment variables, a settings.json for Python-specific formatting, and an extensions.json with at least 8 recommended extensions.

Mini Project: Debug a Real-Time File Scanner

Simulate debugging a Node.js file scanner in VS Code:

  1. Write a simple file scanner that watches a directory and logs file changes
  2. Set up a launch.json that passes the directory path as an environment variable
  3. Add a conditional breakpoint inside the file change handler that triggers only for .exe files
  4. Use the Debug Console to evaluate variables and test expressions while paused
  5. Add a couple of logpoints (breakpoints that log without pausing) for non-critical events

This mirrors the debugging workflow used by Durga Antivirus Pro's real-time protection team.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro