days since this article was written, please be aware of its timeliness
Chrome is a browser and also a powerful debugging tool for front-end engineers. Below are several features I frequently use in my work, which I will introduce one by one.
Breakpoints
This is probably the most commonly used basic feature, but many outsourced colleagues I’ve interviewed don’t know how to use Chrome’s breakpoint debugging—or have heard of it but don’t know how to apply it. Here’s a brief introduction to the basic operations.
To add a breakpoint, you can directly hardcode it in the script by inserting a debugger statement. When the code executes this line, it will pause at this point:

In VSCode, yellow underlines indicate warnings. Generally, this method is not recommended because it offers no clear advantage over console.log and may even be less convenient, as you’ll need to delete it afterward—otherwise, the code remains unusable.
Another approach is to locate the source code directly in the Sources tab of DevTools. Typically, after outputting via console.log, you can click the filename on the right side of the console to view the source code in the Sources tab. After formatting it by clicking the button at the bottom left, you can set breakpoints by clicking the line numbers on the left side of the code for debugging, as shown below:

After hitting a breakpoint, the meanings of the red buttons in the image from left to right are:
-
Continue Execution: When clicked, the breakpoint will directly execute until the next breakpoint is encountered. -
Step Over: If the current breakpoint is not at a function, it behaves the same asStep, executing to the next line. If it is at a function, it will skip the function and continue execution to the next line. -
Step Into: If there is no asynchronous code, it behaves the same asStep, executing to the next line. If there is asynchronous code, it will enter the first line inside the asynchronous code. -
Step Out: When clicked, it exits the current function. -
Step: Executes the next line of synchronous code. UnlikeStep Into, it skips the execution of asynchronous code. If the current breakpoint is at a function, it will enter the first line inside the function call. -
Disable/Enable Breakpoint: When clicked for the first time, it temporarily disables the breakpoint functionality, allowing the code to execute without stopping as if no breakpoint was set. The breakpoints in theBreakpointssection below will appear grayed out:


Pause on exceptionsWhen enabled by clicking the highlight, the code will automatically stop at any thrown error, whether caught or uncaught, and regardless of whether it’s an HTTP error or another type. Note that you must check thePause on caught exceptionsoption below for this to work; leaving it unchecked renders the feature ineffective:

This feature is best enabled after the code has completed execution, when the page has fully loaded, and interaction begins. Otherwise, errors may occur immediately upon entering the page, including legitimate errors in React, preventing the page from loading properly.
Here’s an official screenshot of the breakpoint:

Official Diagram 👆🏻
In the diagram above, below the mentioned buttons, there is a series of toggle ‣ triangle symbols that can be clicked, corresponding to:
-
Watchcan monitor any accessible context variables at the breakpoint for display. If a variable does not exist or is inaccessible—for example, when accessinga.b.cwhereadoes not exist—it will show as unavailable. When the breakpoint is hit, the variables entered here will automatically display without needing to hover the mouse (as shown in the official diagram above) to inspect them, which is very convenient. -
Breakpointsrepresent the existing breakpoints. Checkbox-ticked items are active breakpoints, while unticked ones are temporarily ignored breakpoints (which can be toggled on or off as needed).

The currently executed breakpoint has a yellow background.
-
Threadsindicates the file thread of the current call. The JavaScript thread of the current page is displayed asMain. This section is generally not used, except when debuggingWeb Workeror debugging Chrome browser extensions on the current page. -
Scopedisplays the accessible variable values at the current breakpoint. Due to JavaScript’s closure and call stack features, many variables from closures will be displayed:

Call Stackrefers to the function call stack, where the topmost layer represents the most recent call. You can navigate between different functions by clicking on them. Note that jumping does not actually re-execute the code at that position; it merely allows you to inspect the closure variables at that location.
UI Breakpoints
In some cases, you may not know or have no way to pinpoint why a UI issue occurs in a certain way. For example, your colleague wrote code that changes a button’s color when hovered over. You need to add new logic to this behavior, but you have no idea which file contains their code (they went on vacation without handing over the work—how frustrating!).
You notice that hovering over the button adds a class name to it. In this case, you can use DOM breakpoints for debugging. In the Elements tab, right-click on the element you want to inspect:

UI breakpoints allow code execution to pause right before the specified UI event’s code is executed. UI events include:
-
Subtree modification: If any changes occur in the subtree, such as additions or attribute modifications, the code will break at the point where this logic is about to execute.
-
Attribute modification: If any attributes of the right-clicked element are modified, the code will break at the point where this logic is about to execute.
-
Node removal: If the right-clicked element is removed, the code will break at the point where this logic is about to execute.
For example, in Feishu Docs, when a block receives focus, a focus class name is added to the node:


At this point, you can use attribute modifications to set breakpoints:

By default, the online code is minified. Click the {} button in the bottom-left corner to format it:

After formatting, Chrome creates a new tab and appends :formatted to the filename.

Note that if the element you right-clicked undergoes a parent node change (e.g., the parent node is entirely removed), the UI breakpoint will not trigger.
Overwrite
Charles has a similar feature called Map js (if I recall correctly), and ProxyMan’s equivalent is called Map Local—both serve the same purpose.
Sometimes, when the release/testing pipeline is lengthy (especially for foundational tool components like editors that require package deployment), validating a case quickly can be cumbersome. In such scenarios, Chrome’s Overwrite feature can be useful.
This functionality resembles Charles’ Map js feature, where local files can be served as responses to page requests. You first need to enable this feature in Sources. Of course, if no local file storage location is specified, you’ll be prompted to designate one:

At this point, Chrome will prompt you to grant full access permissions to the local path—simply approve it:

After selecting a local folder (here I chose the ~/Developer/Overwrite folder), you can enable the Overwrite feature:

Then navigate to the Network tab, select a resource such as css/js, and here I chose js:

Note that if Overwrite is not enabled in Sources, the Save for overrides option will not be displayed here.
After that, you can freely modify the file and refresh the page to see the changes take effect.
It’s important to note that if the requested js file includes a timestamp, Overwrite will not work because Chrome uses strict path matching to map files.
Snippet
To be precise, this isn’t exactly a “debugging method,” but I often store code validation snippets here as well. It functions similarly to Sublime (which offers autocompletion for previously entered variables) and is quite handy:

Filesystem
This feature is located in the same position as the ones mentioned above, used to synchronize modifications in the browser to the local file system in real time. It is suitable for simple HTML web services, such as local debugging with server-side frameworks like Express that return js/css/html files.
However, the official documentation explicitly states that this feature is not suitable for React Apps. Since most projects today are built with modern frameworks like React and Vue, this feature is rarely used. Here, we only provide an official screenshot:

Others
MacVim
The overwritten JavaScript files mentioned above are usually minified production code, some of which can be quite large. I typically open them in Vim and format them first. Configuring Vim can be quite cumbersome, while MacVim offers an out-of-the-box experience that can be easily customized for better personal use. The reason I use MacVim is its exceptional performance—it can format files as large as tens of megabytes in just a few seconds. I usually configure js-beautify for formatting. Despite its name, js-beautify can format not only JavaScript but also CSS and HTML.
To use js-beautify, you first need to install vim-plug, a Vim plugin manager: https://github.com/junegunn/vim-plug. For installation steps, refer to: https://github.com/junegunn/vim-plug/wiki/tutorial.
Note: Installation requires “magic” (a proxy or VPN).
For js-beautify, use this: https://github.com/beautify-web/js-beautify.
Here’s my Vim configuration. I use the [] shortcut to invoke js-beautify, so I don’t have to type the command every time:
1 | |
VSCode
VSCode also features breakpoint debugging (thanks to the Chrome kernel), but it can only debug Node applications (it can debug web applications with browser extensions, but there’s no need since Chrome already exists). The basic usage is similar to Chrome, so I won’t elaborate here—just take a look at the image:

-
Previous
Blog Automation Process and Experience Optimization – Part 2 -
Next
Learning Challenges of Underperforming Students
I often wish that when facing some key decisions in life, someone could tell me the best course of action so that I would not waste my precious time. Putting myself in others' shoes, I therefore write blogs often, hoping to record in this tiny corner of the vast Internet the once-in-a-lifetime experiences that matter to me, and to help those who seek help.