VS Code Mastery

The bar: you can navigate, edit, and debug real code in VS Code without reaching for the mouse, and you can hand your whole editor setup to a teammate who gets the same environment on the first clone.

Your editor is the tool you touch more than any other. Every second you waste hunting through menus, mis-clicking tabs, or debugging with console.log is a second stolen from the actual work of shipping software. The good news is that VS Code rewards the small investment: an hour spent learning its keyboard and its config pays back every single day for the rest of your career.

This module is about turning VS Code from a text box into an instrument. You'll learn to move at the speed of thought, wire up the extensions that catch mistakes before they become bugs, and make your setup portable so it travels with you from your laptop to a teammate's screen to a production codebase.

2.1 Core Navigation

Objective: move around a codebase faster than you can describe where you're going.

The single most important key in VS Code is the Command Palette. Anything the editor can do, you can trigger by name from Ctrl/Cmd+Shift+P without memorizing where it lives in a menu. When you don't know the shortcut for something, this is where you start.

The rest of navigation is about jumping, not scrolling. Ctrl/Cmd+P (Quick Open) gets you to any file by typing part of its name. Ctrl/Cmd+Shift+O jumps to a symbol inside the current file; F12 follows a function or component to where it's defined. Ctrl/Cmd+G drops you on a line number. Together these mean you almost never scroll to find code, you jump straight to it.

The common self-taught mistake is living in the file explorer sidebar, clicking folder triangles like it's a filing cabinet. Strong engineers barely open the sidebar. They keep their hands on the keys and let Quick Open and Go to Definition do the walking.

Drill: open the Command Palette with Ctrl/Cmd+Shift+P; jump to files with Ctrl/Cmd+P; list symbols with Ctrl/Cmd+Shift+O; follow a definition with F12; go to a line with Ctrl/Cmd+G; add cursors with Alt+Click and select next match with Ctrl/Cmd+D.

2.2 Essential Extensions

Objective: install and configure the extensions that make the editor catch mistakes for you.

Extensions are how VS Code learns your stack. The high-value set for web work is small and specific. ESLint flags JavaScript problems as you type, and Prettier reformats your file on save so nobody argues about spacing in a code review. Error Lens pulls errors and warnings out of the hover tooltip and prints them inline, right on the offending line, so you see the problem the instant you make it.

GitLens layers git history and blame directly into the editor, so you can see who wrote a line and why without leaving your file. Thunder Client gives you a Postman-style API tester inside VS Code, which is handy when you're building or hitting an endpoint. For styling and Python, Tailwind CSS IntelliSense autocompletes utility classes and the Python extension pack wires up linting, formatting, and debugging in one install.

The gotcha: installing an extension is not the same as configuring it. Prettier does nothing on save until you turn on format-on-save; ESLint can conflict with other formatters if you don't tell VS Code which one wins. An extension you installed but never pointed at your project is just dead weight.

Drill: install and verify ESLint, Prettier, GitLens, Error Lens, Thunder Client, Tailwind CSS IntelliSense, and the Python extension pack; confirm format-on-save actually fires; open a file and read a git blame line through GitLens.

2.3 Workspace Configuration

Objective: configure VS Code so a whole team gets a consistent environment, not just you.

VS Code has two layers of settings. User settings live on your machine and follow you everywhere. Workspace settings live in the project itself, in a .vscode/settings.json file that gets committed to the repo. The rule of thumb: personal taste (your theme, your font) goes in User settings; anything the whole team must agree on (which formatter runs, tab width) goes in Workspace settings so it's identical for everyone who clones the repo.

The .vscode/extensions.json file is how you tell teammates which extensions the project expects. When someone opens the repo, VS Code prompts them to install the recommended set. That's the difference between "works on my machine" and an onboarding that just works.

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

The mistake here is putting machine-specific paths or personal preferences into committed Workspace settings, which then fights every teammate's setup. Keep committed config to what the project genuinely requires, and leave personal choices in your own User settings.

Drill: edit both User and Workspace settings.json; create a .vscode/extensions.json with recommended extensions; add a .vscode/launch.json debug configuration; commit the workspace config and confirm a fresh clone picks it up.

2.4 Integrated Terminal

Objective: run your whole workflow without leaving the editor.

The integrated terminal means you never alt-tab to a separate window to run a command. Open one with the terminal shortcut, and it drops you in your project root with the same shell you use everywhere else. You can spin up several terminals and switch between them, which matters when you're running a dev server in one and a test watcher in another.

Split terminals put two shells side by side in the same panel, which is the natural setup for parallel work: server on the left, logs or a REPL on the right. Terminal profiles let you configure which shell launches and with what arguments, so your integrated terminal matches the environment you configured in your shell dotfiles.

VS Code can also run defined tasks straight from the terminal, so a build or a test suite becomes a named command instead of something you retype. The gotcha for veterans coming from a customized shell: the integrated terminal reads your shell config, so if your aliases or environment aren't loading, the problem is almost always in your profile, not in VS Code.

Drill: create and manage multiple terminals; split a terminal for parallel work; set up a terminal profile; run a defined task from the terminal; confirm your shell config and aliases load inside the integrated terminal.

2.5 Debugging

Objective: debug JavaScript, TypeScript, and Python by inspecting real state instead of guessing.

Debugging with console.log works until it doesn't. The VS Code debugger lets you stop execution and look at exactly what your program is doing. A breakpoint pauses on a line; a conditional breakpoint only pauses when an expression is true (say, when a loop hits the one record that's broken); a logpoint prints a message without pausing at all and without you editing the source.

Once you're paused, the debugger becomes a cockpit. The debug console lets you run expressions in the live paused state, watch expressions track values as you step, and the call stack shows you the exact chain of calls that got you here so you can climb back up to find where things went wrong.

You wire all of this up in a launch.json file. For a Node.js app you point it at your entry file or attach to a running process; for Python, VS Code uses debugpy under the hood to hit breakpoints the same way. The common mistake is a launch.json that points at the wrong file or the wrong working directory, so breakpoints show as unbound and never fire. When a breakpoint won't bind, check the config before you doubt the tool.

Drill: set line, conditional, and logpoint breakpoints; evaluate expressions in the debug console; add watch expressions; walk the call stack; write a launch.json to debug a Node.js app; debug a Python script through debugpy.

2.6 Keyboard Shortcuts

Objective: run the common operations without your hand ever leaving the keyboard.

Speed comes from never breaking rhythm to grab the mouse. That means knowing the shortcuts for file operations (new, save, close, and switching between open files), for editor layout (split the editor, move a file to another group, resize panes), and for the code edits you make constantly: format the document, toggle a comment, and move a line up or down.

Search is its own cluster worth drilling: find and replace in the current file, and find-in-files across the whole project. Refactoring shortcuts like rename-symbol (which updates every reference at once) and extract are where the keyboard genuinely beats manual editing, because they change many places safely from one keystroke.

When a command you use often has no shortcut, or has an awkward one, rebind it. Custom keybindings let you shape the editor to your hands. The mistake is memorizing a shortcut you'll use twice a year; drill the handful you use every hour and let the Command Palette cover the rest.

Drill: practice file ops (new, save, close, switch); split, move, and resize editors; format, toggle-comment, and move lines; find, replace, and find-in-files; rename and extract via refactoring; add a custom keybinding for a command you run often.

2.7 Hands-On Lab: Custom Configuration

Objective: build a portable, professional VS Code configuration you can carry to any project.

What you ship

A complete, reusable editor setup:

  • An exported settings configuration you can drop onto a fresh machine and be productive in minutes.
  • A workspace template with a .vscode/extensions.json recommending your core extensions to anyone who clones it.
  • Working launch.json debug configurations for both a Next.js front end and a FastAPI back end.
  • Custom snippets for the patterns you write over and over, so boilerplate is one tab-completion away.

On the VWC codebase

The Vets Who Code app uses Biome for lint and format, not ESLint and Prettier. When you work in that repo, let its committed .vscode recommendations drive which extensions load, and lean on the Biome extension rather than the generic ESLint/Prettier pair. The debugging, terminal, and navigation skills here carry over unchanged: you'll set breakpoints in the same launch.json style against a Next.js Pages Router app running on src/pages, and Tailwind IntelliSense will autocomplete the project's tw- prefixed classes.