Table of Contents
Fetching ...

Static JavaScript Call Graphs: A Comparative Study

Gábor Antal, Péter Hegedűs, Zoltán Tóth, Rudolf Ferenc, Tibor Gyimóthy

TL;DR

This paper addresses the challenge of constructing precise static call graphs for JavaScript, a language with dynamic features and widespread use. It empirically compares five state-of-the-art static call-graph extractors (WALA, Closure, ACG, npm-cg, and TAJS) on 26 SunSpider benchmarks and 6 real-world Node.js modules, using a unified JSON output and manual validation. The study finds that no single tool is universally best: ACG offers high precision and recall, TAJS provides high precision with lower recall, Closure achieves strong recall with some false positives, WALA detects higher-order calls but with higher memory use and some unknown targets, and npm-cg delivers high precision but poor scalability. Importantly, combining tools (e.g., ACG+TAJS) approaches near-complete coverage (around 99% of true edges) with high precision, highlighting the value of hybrid approaches for practical static analysis. The results illuminate strengths and weaknesses across mature tools and suggest directions for integrating multiple analyses to improve JavaScript call-graph accuracy in real-world software engineering tasks.

Abstract

The popularity and wide adoption of JavaScript both at the client and server side makes its code analysis more important than ever before. Most of the algorithms for vulnerability analysis, coding issue detection, or type inference rely on the call graph representation of the underlying program. Despite some obvious advantages of dynamic analysis, static algorithms should also be considered for call graph construction as they do not require extensive test beds for programs and their costly execution and tracing. In this paper, we systematically compare five widely adopted static algorithms - implemented by the npm call graph, IBM WALA, Google Closure Compiler, Approximate Call Graph, and Type Analyzer for JavaScript tools - for building JavaScript call graphs on 26 WebKit SunSpider benchmark programs and 6 real-world Node.js modules. We provide a performance analysis as well as a quantitative and qualitative evaluation of the results. We found that there was a relatively large intersection of the found call edges among the algorithms, which proved to be 100 precise. However, most of the tools found edges that were missed by all others. ACG had the highest precision followed immediately by TAJS, but ACG found significantly more call edges. As for the combination of tools, ACG and TAJS together covered 99% of the found true edges by all algorithms, while maintaining a precision as high as 98%. Only two of the tools were able to analyze up-to-date multi-file Node.js modules due to incomplete language features support. They agreed on almost 60% of the call edges, but each of them found valid edges that the other missed.

Static JavaScript Call Graphs: A Comparative Study

TL;DR

This paper addresses the challenge of constructing precise static call graphs for JavaScript, a language with dynamic features and widespread use. It empirically compares five state-of-the-art static call-graph extractors (WALA, Closure, ACG, npm-cg, and TAJS) on 26 SunSpider benchmarks and 6 real-world Node.js modules, using a unified JSON output and manual validation. The study finds that no single tool is universally best: ACG offers high precision and recall, TAJS provides high precision with lower recall, Closure achieves strong recall with some false positives, WALA detects higher-order calls but with higher memory use and some unknown targets, and npm-cg delivers high precision but poor scalability. Importantly, combining tools (e.g., ACG+TAJS) approaches near-complete coverage (around 99% of true edges) with high precision, highlighting the value of hybrid approaches for practical static analysis. The results illuminate strengths and weaknesses across mature tools and suggest directions for integrating multiple analyses to improve JavaScript call-graph accuracy in real-world software engineering tasks.

Abstract

The popularity and wide adoption of JavaScript both at the client and server side makes its code analysis more important than ever before. Most of the algorithms for vulnerability analysis, coding issue detection, or type inference rely on the call graph representation of the underlying program. Despite some obvious advantages of dynamic analysis, static algorithms should also be considered for call graph construction as they do not require extensive test beds for programs and their costly execution and tracing. In this paper, we systematically compare five widely adopted static algorithms - implemented by the npm call graph, IBM WALA, Google Closure Compiler, Approximate Call Graph, and Type Analyzer for JavaScript tools - for building JavaScript call graphs on 26 WebKit SunSpider benchmark programs and 6 real-world Node.js modules. We provide a performance analysis as well as a quantitative and qualitative evaluation of the results. We found that there was a relatively large intersection of the found call edges among the algorithms, which proved to be 100 precise. However, most of the tools found edges that were missed by all others. ACG had the highest precision followed immediately by TAJS, but ACG found significantly more call edges. As for the combination of tools, ACG and TAJS together covered 99% of the found true edges by all algorithms, while maintaining a precision as high as 98%. Only two of the tools were able to analyze up-to-date multi-file Node.js modules due to incomplete language features support. They agreed on almost 60% of the call edges, but each of them found valid edges that the other missed.
Paper Structure (29 sections, 2 figures, 7 tables)

This paper contains 29 sections, 2 figures, 7 tables.

Figures (2)

  • Figure 1: Methodology overview
  • Figure 2: Venn diagram of the true/total number of edges found by the tools