Code Graph
Build and query xgrep's code graph — callers, callees, call paths, and inlined-source neighborhoods.
Code Graph
The examples below run against expressjs/express, so you can follow along on a familiar codebase:
git clone https://github.com/expressjs/express && cd express# Build the code graph (auto-cached to .xgrep/graph.json)
xgrep graph build .
# Find callers / callees of a function
xgrep graph callers matchLayer
xgrep graph callees acceptParams
# Show N-hop neighborhood with inlined source code
xgrep graph context matchLayer --depth 2
# Find every function reachable from a function
xgrep graph reachable acceptParams
# Find call paths between two functions
xgrep graph paths <source> <dest>Every command takes --json for machine-readable output.
The graph is auto-cached on first query and rebuilds automatically when source files
change. Function names can be partial matches (e.g. match matches matchLayer);
for an exact match, use the full node ID such as lib/router/index.js::matchLayer.
graph context — the one to reach for
graph context is the most useful single command: it returns topology and inlined
source in one shot, which is ideal for triaging a finding's neighborhood or handing an
LLM exactly the code it needs.
xgrep graph context matchLayer --depth 1# Code context for matchLayer
**Focus**: `matchLayer` (function) at lib/router/index.js:583-589
**Neighborhood**: 1 functions within 1 hops
## lib/router/index.js
### matchLayer (function, L583-589) ← FOCUS
Called by: lib/router/index.js::next
Calls: ?::layer.match
```javascript
function matchLayer(layer, path) {
try {
return layer.match(path);
} catch (err) {
return err;
}
}
```The output is Markdown — topology plus the focus function's source inlined, ready to drop straight into an LLM prompt. See AI agents for a full triage workflow built on this.

Callers and callees
xgrep graph callers matchLayerlib/router/index.js::matchLayer called by:
next [certain] (lib/router/index.js:226)xgrep graph callees acceptParamslib/utils.js::acceptParams calls:
str.split [inferred] (lib/utils.js:127)
parseFloat [certain] (lib/utils.js:133)Each edge is marked certain (a resolved local call) or inferred (a call whose
target xgrep could name but not resolve to a definition — typically a method on a
value or an external/global function).
Call paths
graph paths <source> <dest> reports the call chains between two functions. Both
endpoints must resolve to functions with definitions in the graph; it's most useful
on densely-connected internal code (a request handler down to a specific helper).