Course:Internet & Tools/
Lesson

console.log() debugging is like shining a flashlight in a dark room, you see whatever you point it at, but nothing else. BreakpointWhat is breakpoint?A specific screen width at which a media query applies different CSS rules, or a marker in DevTools where code execution pauses for debugging. debugging is like turning on every light at once. You see every variable, every scopeWhat is scope?The area of your code where a variable is accessible; variables declared inside a function or block are invisible outside it., every function in the call chain, all frozen in time at the exact moment you care about.

This is the most valuable skill for working with AI-generated code. When Copilot writes a function and you are not sure what it does at step 3 of 7, you set a breakpoint and watch it execute one line at a time. No guessing, no adding console.log everywhere, just direct observation.

The debugger statement, your quick entry point

The fastest way to pause AI-generated code is to type debugger; right where you want to inspect. When the browser reaches that line and DevTools is open, execution freezes and the Sources panel opens automatically.

// Copilot generated this - but the total is wrong
function calculateTotal(items, taxRate) {
  let subtotal = 0;

  for (const item of items) {
    debugger; // Pause here - inspect item and subtotal each iteration
    subtotal += item.price * item.quantity;
  }

  const tax = subtotal * taxRate;
  debugger; // Pause here - is tax calculated correctly?
  return subtotal + tax;
}

Once paused, hover over any variable to see its current value. The ScopeWhat is scope?The area of your code where a variable is accessible; variables declared inside a function or block are invisible outside it. panel on the right shows every variable accessible at that point. You can even type expressions in the Console while paused, they execute in the current scope.

Always remove debugger statements before committing. They are harmless when DevTools is closed (the browser ignores them), but they will pause a teammate's browser unexpectedly. Use git diff to check for leftover debugger statements before pushing.
02

Setting breakpoints in the Sources panel

A cleaner approach, one that does not touch your source code, is to set breakpoints directly in the Sources panel. Open the panel, find your file in the file tree on the left, and click any line number. A blue marker appears to confirm the breakpointWhat is breakpoint?A specific screen width at which a media query applies different CSS rules, or a marker in DevTools where code execution pauses for debugging..

The Sources panel offers several types of breakpoints:

TypeHow to set itWhen it pauses
RegularClick a line numberEvery time that line runs
ConditionalRight-click → Add conditional breakpointOnly when your expression evaluates to true
LogpointRight-click → Add logpointNever pauses, just logs a value (like console.log without editing code)
DOMRight-click element in Elements → Break onWhen the DOM node is modified
XHR/FetchSources → XHR/fetch Breakpoints → add URLWhen a matching network request fires
Event listenerSources → Event Listener BreakpointsWhen a specific event type fires (click, keydown, etc.)

Conditional breakpoints are especially powerful when debugging AI-generated loops:

// ChatGPT generated this loop over 10,000 users
// You only care about the one that's breaking
for (const user of users) {
  processUser(user);
}

// Right-click the line, choose "Add conditional breakpoint":
// user.id === 'usr_broken' && user.status === 'error'
// Now execution only pauses for that exact user

Logpoints are a game-changer for AI code: you can add logging without modifying the source file. Right-click a line number, choose "Add logpoint," and type an expression like 'User:', user.name, 'Total:', total. The value logs to the console every time that line executes, no code changes needed.

03

Navigation controls, stepping through AI logic

Once paused, four buttons in the toolbar control how you move forward:

Resume  (F8)         → Continue to the next breakpoint or end of script
Step Over (F10)      → Execute the current line, skip into function calls
Step Into (F11)      → Enter the function being called on this line
Step Out (Shift+F11) → Finish the current function, return to the caller

The mental model: Step Over means "I trust this function, just run it." Step Into means "I want to see what happens inside." When debugging AI code, you Step Over the parts you understand and Step Into the parts you do not.

// Copilot generated this - stepping through it
async function loadDashboard(userId) {
  const user = await getUser(userId);    // Step INTO this if user data looks wrong
  const prefs = applyDefaults(user.prefs); // Step OVER - simple merge, probably fine
  const data = await fetchDashboard(user); // Step INTO - this is where the bug might be
  return renderDashboard(data, prefs);     // Step INTO if the render output is wrong
}
04

Inspecting variables while paused

While paused at a breakpointWhat is breakpoint?A specific screen width at which a media query applies different CSS rules, or a marker in DevTools where code execution pauses for debugging., you have three ways to inspect values:

Hover

Hover your cursor over any variable or expression in the source code. A tooltip shows the current value. You can expand objects and arrays inline.

ScopeWhat is scope?The area of your code where a variable is accessible; variables declared inside a function or block are invisible outside it. panel

The Scope panel on the right lists every variable accessible at the current point of execution:

ScopeWhat it contains
LocalVariables declared in the current function
ClosureVariables captured from outer functions (closures)
ScriptModule-level variables
Globalwindow-level variables

Watch expressions

Pin any JavaScript expression to the Watch panel and it updates every time you step. This is invaluable for monitoring computed values:

// Add these to the Watch panel while debugging AI code:
items.filter(i => i.price > 100).length
JSON.stringify(user.permissions)
response.headers.get('content-type')
When debugging AI-generated React components, add this and props to the Watch panel (for class components) or the state variable names (for hooks). AI tools frequently pass the wrong props or initialize state with the wrong type.
05

The call stackWhat is call stack?The internal mechanism that tracks which function is currently executing and which called it - visible in error stack traces and browser DevTools., understanding AI code's execution flow

The Call Stack panel shows every function that ran to get to the current line. This is a breadcrumb trail of execution:

calculateTax     (utils.js:45)    ← current position (paused here)
processLineItem  (cart.js:23)     ← called by this
calculateTotal   (cart.js:12)     ← called by this
handleCheckout   (Checkout.jsx:67) ← triggered by this

Clicking any frame in the call stack jumps you to that function's context, letting you inspect the variables that were in scopeWhat is scope?The area of your code where a variable is accessible; variables declared inside a function or block are invisible outside it. at that point. This is invaluable for understanding how data transforms as it passes through multiple AI-generated functions.

06

Debugging async code

The debugger understands async/await and will pause at each await as if it were synchronous:

// Claude generated this data loader - step through it
async function loadUserProfile(userId) {
  const user = await fetchUser(userId);
  // Pause here - inspect user object. Is the shape correct?

  const posts = await fetchPosts(user.id);
  // Pause here - did fetchPosts get the right ID?

  const enriched = await enrichWithAnalytics(user, posts);
  // Pause here - what does the final object look like?

  return enriched;
}

Chrome DevTools shows the full async call stackWhat is call stack?The internal mechanism that tracks which function is currently executing and which called it - visible in error stack traces and browser DevTools., you can see what triggered an async operation even after the original synchronous code has already finished running. Enable it by checking "Async" in the Call Stack panel.

07

Source maps, debugging the code you actually wrote

If you are writing TypeScript, using Vite, or using any bundler, the code the browser runs looks nothing like what you wrote. Source maps link the compiled output back to your original files.

Most modern toolchains (Vite, Next.js, Create React App) generate source maps automatically in development mode. To verify they are working, open the Sources panel and look for a folder with your project name, your original .ts or .jsx files should be there. You can set breakpoints in those original files and the debugger pauses correctly even though the browser is running compiled code.

08

Quick reference

ActionShortcutWhen to use
ResumeF8Move to next breakpoint
Step OverF10Skip function you trust
Step IntoF11Enter function you want to inspect
Step OutShift+F11Leave current function
Toggle breakpointClick line numberMark where to pause
Conditional breakpointRight-click line → Add conditionalPause only on specific condition
LogpointRight-click line → Add logpointLog without editing code
Deactivate all breakpointsCtrl+F8Temporarily disable all breakpoints