Chrome Debugging: How to Debug JavaScript in DevTools
To debug in Chrome, open DevTools (F12, or Ctrl+Shift+I on Windows/Linux, Cmd+Option+I on Mac), go to the Sources panel, open your script and click a line number to set a breakpoint. Reload or trigger the code, and Chrome pauses on that line so you can inspect variables in the Scope pane and step through with F10 (step over) and F11 (step into). For quick checks, the Console (Ctrl+Shift+J / Cmd+Option+J) runs JavaScript against the live page.
This guide covers the Chrome DevTools debugger as it works in October 2026: the shortcuts, every breakpoint type worth knowing, debugging network calls and Node.js, and debugging Chrome on Android.
Open the Chrome debugger: shortcuts
| Action | Windows / Linux | Mac |
|---|---|---|
| Open DevTools (last panel used) | F12 or Ctrl+Shift+I | Cmd+Option+I (or Fn+F12) |
| Open the Console | Ctrl+Shift+J | Cmd+Option+J |
| Inspect an element | Ctrl+Shift+C | Cmd+Option+C |
| Pause / resume script | F8 or Ctrl+\ | F8 or Cmd+\ |
| Step over next call | F10 or Ctrl+' | F10 or Cmd+' |
| Step into next call | F11 or Ctrl+; | F11 or Cmd+; |
| Step out of current function | Shift+F11 or Ctrl+Shift+; | Shift+F11 or Cmd+Shift+; |
| Open a file in Sources | Ctrl+P | Cmd+P |
| Run a DevTools command | Ctrl+Shift+P | Cmd+Shift+P |
You can also right-click anything on the page and choose Inspect, or use the three-dot menu > More tools > Developer tools (Open Chrome DevTools). To open DevTools automatically for every new tab, start Chrome with --auto-open-devtools-for-tabs.
Debug JavaScript step by step
A worked example: a "Total" button shows 23 instead of 5.
<input id="a" value="2"> + <input id="b" value="3">
<button id="sum">Total</button> <span id="out"></span>
<script>
document.getElementById('sum').addEventListener('click', () => {
const a = document.getElementById('a').value;
const b = document.getElementById('b').value;
const total = a + b; // bug: string concatenation
document.getElementById('out').textContent = total;
});
</script>
- Open DevTools and select Sources. Press Ctrl+P / Cmd+P and open the file.
- Click the line number of
const total = a + b;. A blue marker shows the breakpoint. - Click Total on the page. Execution pauses on that line.
- Look at the Scope pane:
ais"2"andbis"3", both strings. That's the bug. - Press F10 to step over the line and watch
totalbecome"23". - Test a fix without leaving the page: type
Number(a) + Number(b)in the Console while paused. The Console runs in the paused scope, so it can seeaandb. - Press F8 to resume.
While paused, the Call Stack pane shows how you got there (right-click a frame for Restart frame or Copy stack trace), and the Watch pane re-evaluates expressions you add at every step (JavaScript debugging reference). You can also edit the top function in the editor and save with Ctrl+S / Cmd+S: DevTools applies the change live and restarts that function.
Breakpoint types that save the most time
Plain line breakpoints get you far, but these are what make Chrome debugging fast (Pause your code with breakpoints):
| Breakpoint | When to use | How to set it |
|---|---|---|
| Line of code | You know where to look | Click the line number in Sources |
debugger; statement |
You're editing the code anyway | Add debugger; to your source |
| Conditional | A loop or handler runs often, the bug only hits one case | Right-click the line number > Add conditional breakpoint |
| Logpoint | You want a console.log without editing code |
Right-click the line number > Add logpoint |
| DOM change | Something changes an element and you don't know what | Elements > right-click node > Break on > subtree, attribute or node removal |
| XHR/fetch | You want to see who sends a request | Sources > XHR/fetch Breakpoints > add a URL substring |
| Event listener | You don't know which handler runs on click or keydown | Sources > Event Listener Breakpoints > tick the event |
| Exceptions | Errors are swallowed or thrown far from the cause | Breakpoints pane > Pause on uncaught exceptions / Pause on caught exceptions |
| Function | Pause whenever a function is called | Run debug(myFunction) in the Console |
Logpoints are the underused one. A logpoint like "cart", cart.items.length prints to the Console every time the line runs, and it disappears when you remove it, so no stray console.log ends up in a commit. To stop a noisy line from pausing at all, right-click it and choose Never pause here.
Skip library code with the ignore list
When stepping keeps landing in framework or bundler code, right-click the script in the editor, the file tree or the Call Stack and choose Add script to ignore list. The debugger then steps over that code and hides its frames. Manage the list in Settings > Ignore list. Chrome also ignore-lists known third-party scripts automatically when your build's source maps mark them as third party.
Using the Chrome console as a debugger
The Console is the quickest way to check a theory:
$0is the element currently selected in the Elements panel;$_is the last result.$('selector')and$$('selector')work likequerySelectorandquerySelectorAll.copy(obj)copies a value to your clipboard as JSON.monitorEvents(window, 'resize')logs events as they fire;unmonitorEventsstops it.console.table(rows)prints arrays of objects as a table.- The Create live expression (eye icon) at the top of the Console keeps an expression updated as the page runs.
Use the sidebar's level filter (Errors, Warnings, Info, Verbose) to cut noise. Verbose shows extra browser messages like violations and is hidden by default.
Debug network requests
In the Network panel, click a request to see headers, payload, response and timing. A few things to know:
- Preserve log keeps requests across page loads, which you need when debugging redirects or logins.
- Disable cache only applies while DevTools is open.
- The Initiator column, and the Initiator tab on a request, shows the line of JavaScript that sent it. Click through to land in Sources.
- Right-click a request > Copy > Copy as cURL to replay it in a terminal.
- To test a fix to an API response or a header (for example a CORS header) without touching the server, right-click a request and choose Override content or Override headers. DevTools asks for a local folder to store Local overrides (Override web content and HTTP response headers locally). Turn them off in Sources > Overrides when you're done, because caching is disabled while they're on.
Debug Node.js with Chrome DevTools
The same debugger works for server code. Start Node with the inspector:
node --inspect-brk server.js # pauses before your code runs
Then open chrome://inspect and click inspect under Remote Target, or click Open dedicated DevTools for Node. The inspector listens on 127.0.0.1:9229 by default. Don't bind it to 0.0.0.0: anyone who can reach the port can run code as your process. For a remote server, keep it on localhost and use an SSH tunnel (Node.js debugging guide).
Chrome debugging on Android
To debug a page in Chrome on an Android phone from your desktop (Remote debug Android devices):
- On the phone, enable Developer options, then turn on USB debugging.
- On your computer, open
chrome://inspect#devicesand make sure Discover USB devices is ticked. - Connect the phone by USB, directly rather than through a hub.
- Accept the Allow USB debugging? prompt on the phone. Until you do, the device shows "Pending authentication".
- When the device model appears, click Inspect under the tab you want. A full DevTools window opens on your computer.
Apps that use WebView with debugging enabled show up in the same list. Chrome on iPhone is a different story: it's debugged through Safari's Web Inspector on a Mac, covered in our guide to dev tools for Chrome on iOS.
AI assistance in DevTools
Chrome DevTools includes an AI assistance panel powered by Gemini. It can explain a failing network request, a CSS layout problem, a source file or a performance trace. It's off by default; turn it on in Settings > AI assistance. It requires being signed in to Chrome, being 18 or older and living in a supported region, and Google labels it experimental (AI assistance). Check its answers against what the debugger actually shows. Don't use it on pages with data you aren't allowed to share with Google.
Chrome debug logs
"Chrome debug log" sometimes means the browser's own log rather than the Console. To capture it, quit Chrome and relaunch it with --enable-logging --v=1. Chrome writes chrome_debug.log to its user data directory, overwritten on every restart (Chromium: enable logging). You rarely need this for web development, but it helps when the browser itself crashes or an extension misbehaves.
Limitations
- DevTools debugs what runs in the browser. For a bug in server code, attach to Node (above) or your backend's own debugger.
- Without source maps, minified production code is hard to step through. Ship source maps to your error tracker, or at least to staging.
- Changes made in Elements or the Console are lost on reload. Use Local overrides or a Workspace folder if you want them to stick.
For more tools beyond the browser, see DevHunt's testing tools and IDE categories, and our guide to Redux DevTools if you debug React state.
FAQ
How do I open the debugger in Chrome?
Press F12 or Ctrl+Shift+I (Mac: Cmd+Option+I) and select the Sources panel. A debugger; statement in your code also pauses there, as long as DevTools is open.
Is there a Chrome debugger extension I need to install?
No. The debugger is built into Chrome. For VS Code, the old "Debugger for Chrome" extension is deprecated because VS Code's built-in JavaScript debugger can launch and debug Chrome or Edge directly.
Why doesn't my breakpoint get hit?
The usual causes: the code already ran before you set it (reload the page), the file in Sources isn't the one actually executing (a cached or duplicate bundle), the source map is out of date, or the script is on the ignore list. Also check that Deactivate breakpoints (Ctrl+F8 / Cmd+F8) isn't on.
How do I debug Chrome on a phone?
For Android, connect the phone by USB with USB debugging enabled and open chrome://inspect#devices on your computer. For iPhone, use Safari's Web Inspector on a Mac.
What's the difference between the Console and the Sources debugger?
The Console runs code and shows logs; it can't stop execution. The Sources panel pauses code at a breakpoint so you can see every variable at that moment. Use both together: pause in Sources, then test expressions in the Console.