Across google/zx’s 327 functions, 8 are rated critical — but not all critical functions are equal. transformMarkdown in src/md.ts is the only one in the active-risk category: touched twice in the last 30 days, last changed 18 days ago, with a CC of 18 and a nesting depth of 5. Every edit there lands on a live regression surface. _pipe in src/core.ts and formatCmd in src/log.ts are a different kind of problem — structural debt: untouched for 112 and 39 days respectively, but carrying fan-outs of 27 and 13 with CCs of 15 and 16. zx is Google’s JavaScript shell-scripting toolkit, and the distinction matters for prioritization: fix transformMarkdown first because it is changing now; schedule _pipe and formatCmd before the next development push into those subsystems.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
transformMarkdown | src/md.ts | 14.4 | 18 | 5 | 9 |
_pipe | src/core.ts | 12.7 | 15 | 2 | 27 |
formatCmd | src/log.ts | 12.0 | 16 | 6 | 13 |
main | examples/fetch-weather.mjs | 11.4 | 8 | 2 | 15 |
retry | src/goods.ts | 10.5 | 11 | 3 | 6 |
Codemod / Tooling Files in Results
The function main in examples/fetch-weather.mjs appears in the top five with a risk score of 11.4. This is an example script shipped with the repository, not production library code — and it is structural debt, not example churn: it has not been touched in over three months. Its fan-out of 15 reflects accumulated structural complexity in the example code rather than recent activity. To focus future analyses on library source only, add "exclude": ["examples/"] to your .hotspotsrc.json.
Hotspot Analysis
transformMarkdown — src/md.ts
Based on its name and location, transformMarkdown almost certainly handles the parsing and transformation of Markdown source into executable zx script form — a core feature that allows zx to run scripts embedded in .md files. Its cyclomatic complexity of 18 means there are at least 18 independent execution paths to reason about and test, its max nesting depth of 5 crosses the threshold where control flow becomes genuinely hard to follow, and a fan-out of 9 means it delegates to nine distinct functions whose behavior it depends on. With a recent commit activity of 13.74 — the highest in the repository — this function is being actively changed, making every one of those 18 paths a live regression surface. The complex_branching, deeply_nested, and exit_heavy patterns all co-occur here, and the long_function flag suggests the branching is not spread across helpers but concentrated in one place.
Recommendation: Add a characterization test suite that covers each of the 18 logical paths before any further changes, then extract the deeply nested conditional blocks into named sub-functions to bring nesting depth below 4 and reduce the CC toward single digits.
_pipe — src/core.ts
The name _pipe and its location in src/core.ts suggest this function manages the piping of process I/O streams — a foundational operation that most of zx’s process-chaining API likely depends on. Its fan-out of 27 is the most telling metric here: calling 27 distinct functions means _pipe acts as a coordination hub, and a change to its behavior or signature can ripple across a very wide blast radius. The god_function pattern confirms this — it is doing far more than one thing. Its CC of 15 adds 15 independent paths on top of that coupling. _pipe hasn’t been touched in 112 days, which makes it structural debt rather than an immediate live risk — but its blast radius means any future change there is high-stakes. The exit_heavy pattern means multiple return conditions are scattered through the function, compounding test-coverage requirements.
Recommendation: Map the 27 callees to understand which responsibilities can be delegated to focused sub-functions, then extract cohesive groups of callees into separate, single-purpose helpers — this will reduce fan-out, lower CC, and limit the blast radius of future changes to core piping logic.
formatCmd — src/log.ts
Inferred from its name and location, formatCmd is responsible for rendering shell command representations into the log output — a function that must handle varied command shapes, quoting, escaping, and display concerns. A max nesting depth of 6 is a strong refactoring signal on its own; combined with a CC of 16 and a fan-out of 13, it is clear this function is handling multiple distinct formatting concerns without decomposition. The god_function and complex_branching patterns together indicate that formatting decisions are tangled with output logic in a way that makes each new case harder to add safely. formatCmd hasn’t been touched in 39 days — it is structural debt, not an active regression risk — but its nesting depth and complexity mean the next developer to edit it will be working in difficult terrain without a safety net.
Recommendation: Extract each distinct formatting concern — for example, token quoting, argument joining, and output colorization — into dedicated functions, then test each independently; this will reduce the nesting depth and give each branch its own test surface.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
god_function | 4 |
exit_heavy | 3 |
complex_branching | 2 |
deeply_nested | 2 |
long_function | 2 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Key Takeaways
transformMarkdownin src/md.ts has a cyclomatic complexity of 18 and a recent commit activity of 13.74 — add characterization tests covering all 18 paths before the next change lands there._pipein src/core.ts calls 27 distinct functions, giving it the widest blast radius in the codebase; map its callees and extract cohesive responsibilities into focused helpers to contain future change risk.formatCmdin src/log.ts reaches a nesting depth of 6 — extract each formatting concern into its own function to bring depth below 4 and give each branch an independently testable surface.
Reproduce This Analysis
git clone https://github.com/google/zx
cd zx
git checkout 98531fcf3455500dcc76b5f688ff20d57fbb1d12
hotspots analyze . --mode snapshot --format json --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →