Visualizing call trees

See how JavaScript Studio crawls your source code

A lot has happend since last weeks announcement. The post on making JavaScript Studio publicly available was on the hacker news front page which brought a lot of signups and some very good feedback. The ground-breaking new way to find runtime errors can now show the call tree of how it analyzed your program.

It’s kind of a mystery how JavaScript Studio scans your source code for runtime errors. To demystify it a little, a new feature allows you to understand how it crawls your source code.

To see it in action, update the CLI with npm install @studio/cli -g and use the studio command as before. Let’s analyze the asap library:

❯ npm install asap
+ asap@2.0.6
added 1 package in 0.519s
❯ browserify --require asap --debug -s asap | studio -g asap

Here is what it looks like:

There’s a lot of information there, so what are you looking at?

Browserify prelude

The first section with all the anonymous functions (ƒ()) shows the Browserify prelude and how the main module was loaded. It’s calling makeRequestCallFromTimer(callback) twice.

Public API

The second part with the green asap(task) call is the public API of the module. You can see that the main function internally creates a new RawTask() and calls rawAsap(task).

An API with a few more functions looks like this:

❯ npm install listen
+ listen@1.0.1
added 1 package in 0.556s
❯ browserify --require listen --debug -s listen | studio -g listen

All green functions prefixed with a dot are exposed. JavaScript Studio crawls the entire API, including returned functions, objects and properties on functions. The white nodes are calls made within the library, so you can see how deep an API call goes or if multiple exposed functions call the same internal functions.

If a function throws an exception, it is marked with throws. The [INCOMPLETE] label means that the analyzer wasn’t able to fully process the given function. If a runtime error is detected, it gets marked with a red [RUNTIME ERROR] label. The file path is shown whenever a function call enters a new file.

Event handlers

In the first example you might have noticed the yellow [setInterval] and [setTimeout] calls. These are triggered event handlers. To distinguish events from ordinary calls, they’re highlighted and prefixed with the event name. Consider this script:

function test() {}
document.body.addEventListener('click', function () {
test()
})

Sending this to studio produces:

JavaScript Studio finds the registered event and invokes it with a click event. This also works for load, mouseover or any other kind of event. It also finds events that are assigned, like document.body.onload = function (e) {}.

Available now

The new feature is already available in JavaScript Studio. Just update the CLI with npm i @studio/cli -g to see the new call trees. This also works with the monthly free tier. If you don’t have an account yet, just sign in with GitHub.

Thanks for reading and sharing!