A comprehensive static analysis tool for TypeScript and JavaScript source code that
produces the canonical CodeLLM-DevKit (CLDK) analysis.json — a symbol table plus a
resolver-based call graph — using the TypeScript compiler via ts-morph.
It is the TypeScript backend behind CLDK,
mirroring its Python and
Java siblings.
- Bun 1.0 or higher (used to run and compile the analyzer)
The analyzer resolves types and call targets with the TypeScript compiler, so the project
being analyzed should be a normal Node/TypeScript project. By default, the analyzer
materializes the project's dependencies (node_modules) so that imported library calls can
be resolved as phantom (external) nodes; pass --no-build to reuse an already-prepared
node_modules.
curl -fsSL https://bun.sh/install | bashClone the repository and install dependencies:
git clone https://github.com/codellm-devkit/codeanalyzer-ts
cd codeanalyzer-ts
bun installCompile a standalone native binary (no Bun/Node required to run it afterward):
bun run build # → dist/codeanalyzer-typescriptYou can also run the analyzer directly from source without compiling:
bun run start -- --input /path/to/typescript/projectThe analyzer provides a command-line interface for performing static analysis on TypeScript/JavaScript projects.
codeanalyzer-typescript --input /path/to/typescript/projectTo view the available options, run codeanalyzer-typescript --help:
Usage: codeanalyzer-typescript [options]
CLDK TypeScript analyzer — emits the canonical analysis.json
(symbol table + resolver call graph).
Options:
-i, --input <path> project root to analyze
-o, --output <dir> output directory for analysis.json
(omit ⇒ compact JSON to stdout)
-f, --format <fmt> output format: json | msgpack (default: "json")
-a, --analysis-level <n> 1 = tsc resolver call graph + RTA (default);
2 = + CodeQL enrichment (default: "1")
-t, --target-files <paths...> restrict analysis to specific files (incremental)
--skip-tests skip test trees (default)
--include-tests include test trees
--eager force a clean rebuild instead of reusing the cache
--lazy reuse the cache (default)
--no-build skip dependency materialization
(use a prepared node_modules)
--no-phantoms disable phantom (external) nodes for imported/
required library calls
-c, --cache-dir <dir> cache/intermediate directory
-v, --verbose increase verbosity (repeatable)
-h, --help display help for command
-
Basic analysis (symbol table + call graph):
codeanalyzer-typescript --input ./my-ts-project
This prints the analysis to stdout as compact JSON. To save it instead, use
--output:codeanalyzer-typescript --input ./my-ts-project --output /path/to/analysis-results
The results are written to
analysis.jsonin the specified directory. -
Change output format to msgpack:
codeanalyzer-typescript --input ./my-ts-project --output /path/to/analysis-results --format msgpack
This saves the results to
analysis.msgpack, a binary format that is more compact for storage and transmission. -
Deeper analysis with CodeQL enrichment (experimental):
codeanalyzer-typescript --input ./my-ts-project --analysis-level 2
Every run produces a symbol table and a call graph. At level 1, edges come from the TypeScript compiler's resolver plus Rapid Type Analysis (RTA), with phantom nodes for calls into imported libraries. Level 2 additionally merges in CodeQL-derived edges.
-
Incremental analysis of specific files:
codeanalyzer-typescript --input ./my-ts-project --target-files src/a.ts src/b.ts
Restricts the analysis to the named files, reusing the cached analysis for the rest of the project.
-
Force a clean rebuild with a custom cache directory:
codeanalyzer-typescript --input ./my-ts-project --eager --cache-dir /path/to/custom-cache
--eagerrebuilds the analysis cache from scratch. If--cache-diris omitted, the cache defaults to.codeanalyzerinside the project root.
By default, analysis results are printed to stdout as compact JSON. When --output is given,
results are saved to analysis.json (or analysis.msgpack with --format msgpack) in the
specified directory.
The output document is a TSApplication with the following top-level shape:
Caller- and callee-side identifiers are produced by a single signature canonicalizer, so call
graph source/target values byte-match the corresponding symbol_table (or
external_symbols) keys.
This project uses Bun as its toolchain.
git clone https://github.com/codellm-devkit/codeanalyzer-ts
cd codeanalyzer-ts
bun installbun run start -- --input /path/to/typescript/projectbun run typecheckApache 2.0 — see LICENSE.

{ "symbol_table": { /* file path → module (classes, interfaces, enums, type aliases, functions, namespaces, variables, …) */ }, "call_graph": [ /* CALL_DEP edges: { source, target, weight, provenance, tags } keyed by callable signature */ ], "external_symbols": { /* phantom stubs for call targets outside the project (imported libraries / Node builtins) */ }, "entrypoints": { /* framework-detected entrypoints (empty at level 1) */ } }