One of the key features of Nuclide is its multiple-language debugging support provided with a debugger interface inspired by the familiar Chrome DevTools. The Nuclide Debugger provides many capabilities allowing you to have a productive debug loop, including inspection, watches, setting breakpoints, step in/over/out, etc.


Attach to a running debug target via Cmd-Shift-A (Ctrl-Shift-A on Linux and Windows). You can also toggle the Debugger through the Command Palette and the Nuclide toolbar’s Toggle Debugger icon. You can also launch a new target with the debugger attached via Cmd-F8 (Ctrl-F8 on Linux and Windows).

You can also bring up the Debugger panel by choosing Debugger -> Show from the Nuclide menu.


Nuclide supports debugging for multiple languages and platforms. However, there are some basic debugging concepts that apply across all languages. Debugging a Node project will be used to help illustrate the points described here.

Debuggable Target

Specific details are provided for each language or platform, but in general, to begin debugging code in Nuclide, you need to either launch a debug process from within Nuclide (e.g., iOS from the Buck toolbar) or attach to a currently running process (e.g., node) for debugging.


If you have a Node project running (e.g, via npm start or node yourfile.js), press Cmd-Shift-A (Ctrl-Shift-A on Linux) to toggle the Debugger Attach Dialog. Then, attach Nuclide to the relevant node process.

If you have multiple processes running with the same name, you can use something similar to ps aux | grep <process-name> or Apple’s Activity Monitor to find the Process ID (PID) that matches with the process in the list in Nuclide’s Debugger Selection window.

Once you attach to a process, you will see a confirmation of the attachment in the command-line for that process.

$ node read.js
Starting debugger agent.
Debugger listening on port 5858

After attaching to the process by clicking Attach, you should see the Debugger Controls to the right of the Editing Area.


To set a breakpoint in Nuclide, you use the gutter. Click to the left of each line number in the file(s) in which you want Nuclide to break the running program. Then as the program is running, if a line on which a breakpoint is set is hit, the program halts, and you are able to perform debugging tasks such as step and evaluation from that point.

There is currently only one type of breakpoint called a source breakpoint. This is a breakpoint on one line of code. We are looking into ways to support functional, conditional, and other types of breakpoints.


Here we have breakpoints on lines 13 and 18 of read.js.

In the main debugging tab of the Debugger, you will see what breakpoints are set as well.


The Debugger Controls are the information control center for the Nuclide Debugger.

In addition to the specialized areas described below, it also provides mouse-clickable execution, stepping, and breakpoint options.

Call Stack

The Call Stack area shows you where you came from to get to your current point in the code. The top function is where you currently are, the function below the top is the one that called the current function, and so on. Clicking on any function in the call stack will change the scope information so that it is relevant to that function.


The Breakpoints area shows you all the places in your project where you have breakpoints set. If any are highlighted, that means that you have now hit that breakpoint while running the code. Clicking on a breakpoint in this list will move your cursor to its line of code in the Editing Area. You can deactivate/reactive breakpoints by clicking the checkmark next to each one. Right-clicking in the area will give you the option to quickly remove, enable, or disable all breakpoints at once.

Unresolved Breakpoints

These are breakpoints that cannot be resolved by the debugger. The most likely cause of an unresolved breakpoint is putting a breakpoint on code that is not part of the project on which the debugger process is attached. For some languages, this can also indicate that the program was built without debug symbols (check your compiler flags!), or that the symbols are missing or do not match the binary being debugged.


The Scopes pane shows you information about variables based upon the current point in the running of the code. Which scopes are visible depends on the language being debugged.

Watch Expressions

The Watch Expressions area is for you to keep track of the values of global and local variables. To add a new value to track, enter it in the add new watch expression text box. To remove a watched variable, click the x icon of the variable you wish to delete.


Here we have breakpoints set on line 10 of read.js and line 3 of math.js. We set watches on two global variables (num1 and num2) in the read.js file. The call stack shows that we are currently in the processSum method and started from the onData method.


You can detach the debugger from the current process by clicking “X” to close the debugger controls pane, or by clicking the “stop” button. This will stop the entire debugging session for that process, but will not kill the target.


It is essential for any debugger to have a mechanism to step into, over, and out of code. The Nuclide Debugger provides stepping functionality with shortcuts within the Debugger itself and via the keyboard.


Assume we have a breakpoint set at line 22 of read.js (before the call to processSum()).

The following shows what happens when you step into the function. The code execution steps into the actual processSum() function itself.

The following shows what happens when you step over the function. processSum() is fully executed, and we move on to closing the readline object.

You can even step into a function that exists in another module.


The Nuclide Debugger supports REPL via the Console tab.

When you hit a breakpoint during your debugging session, you can use the Console to write expressions, call functions, etc. using the current state of the program at the breakpoint.

For Hack and PHP debugging, hitting a breakpoint is not necessary to use the REPL support of the Nuclide Debugger. If you do not hit a breakpoint, then REPL is run in the global context as opposed to the current stack frame if a breakpoint is hit.

For LLDB-based debugging, REPL runs LLDB debugger commands as opposed to evaluating code in the Debugger.


Here we have a breakpoint before printing out the sum of the two global variables num1 and num2. This shows printing out the values of the global and local variables, writing simple expressions, calling a function in another module (math.add()), and inspecting objects.

Language Specific Debugging

While the general process for debugging in Nuclide is similar, there are platform and language specific debugging workflows that require discussion and illustration.

Platform Specific Debugging

Buck projects can be more easily debugged via the Task Runner.