A caller inventory answers one question: for every function, method or exported symbol, which places in the repository can reach it. That answer decides whether you can delete a symbol safely, which packages a change ripples into, and whether a dependency bump is inert. The question sounds trivial and is not. A monorepo amplifies every difference between methods because the work scales with file count and with the number of packages that must be resolved before a single import can be understood.
Before picking a tool, write down the precision you need. A pass that answers "which files mention this symbol" is enough for a delete-and-observe workflow. A pass that answers "which typed call sites dispatch to this implementation" needs resolved types and a handle on dynamic dispatch. Those are different artifacts, and choosing a tool before settling the requirement is the most common way teams end up running an expensive pass nobody trusts.
The published research is blunt about the difficulty. A comparative study of five static JavaScript call-graph tools found that only two could analyze up-to-date multi-file modules, and while those two agreed on almost 60 percent of call edges, each found valid edges the other missed (Static JavaScript Call Graphs). If five mature tools disagree about the same codebase, combining methods beats hunting for one perfect tool.



