Of Preact’s 777 analyzed functions, 27 land in the critical band, and the two highest-risk functions in actual project code — diff and diffElementNodes in src/diff/index.js — are both in the ‘fire’ quadrant, meaning they are structurally complex AND actively changing at this moment. diff carries a recent commit activity of 17.35 alongside a cyclomatic complexity of 76, making it a live regression risk rather than a backlog cleanup item. Preact is a fast 3kB alternative to React; the structural weight concentrated in its core reconciler is worth understanding before the next development push.
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 |
|---|---|---|---|---|---|
<anonymous> | test/fixtures/preact.js | 20.2 | 103 | 10 | 78 |
diff | src/diff/index.js | 19.8 | 76 | 9 | 26 |
initDebug | debug/src/debug.js | 18.6 | 50 | 7 | 36 |
diffElementNodes | src/diff/index.js | 17.3 | 63 | 7 | 11 |
handleDomVNode | compat/src/render.js | 16.3 | 45 | 10 | 12 |
Non-Production Files in Results
The top-ranked function by activity risk score is an anonymous function in test/fixtures/preact.js with a cyclomatic complexity of 103, nesting depth of 10, and fan-out of 78 — the most extreme structural metrics in the dataset. This is a test fixture file, almost certainly a bundled or compiled copy of Preact itself used to drive integration tests rather than production source code. Its metrics reflect the full library surface rather than a single authored function. To exclude it from future analyses, add the following to your .hotspotsrc.json: { "exclude": ["test/fixtures/"] }.
initDebug in debug/src/debug.js (risk score 18.6, CC 50, ND 7, FO 36) ranks third overall but is the debug tooling layer — active primarily during development, not on the production rendering path. It is excluded from the three prioritised hotspot sections above for that reason. If your team ships the debug build in production or actively develops the debug tooling, the same extract-method approach recommended for diff applies here.
Hotspot Analysis
diff — src/diff/index.js
As the primary entry point for Preact’s virtual DOM reconciliation, diff is responsible for comparing old and new vnodes and determining what DOM mutations are required — the core of what makes Preact work. A cyclomatic complexity of 76 means 76 independent execution paths through a single function, each a required test case and a potential bug surface; a max nesting depth of 9 means reasoning about inner logic requires tracking nine levels of control flow simultaneously. Critically, this function is in the ‘fire’ quadrant with a recent commit activity of 17.35, meaning it is both maximally complex and under active change right now — every commit here is a live regression risk across the entire rendering pipeline.
Recommendation: Write characterization tests covering edge-case vnode transitions before touching this function further, then extract the most independent branching sub-concerns (e.g. component lifecycle handling, keyed reconciliation) into separate, individually testable helpers to bring the CC below 20 per unit.
diffElementNodes — src/diff/index.js
Sitting alongside diff in src/diff/index.js, diffElementNodes almost certainly handles the lower-level reconciliation of concrete DOM element nodes — attribute patching, child diffing, and namespace handling. Its cyclomatic complexity of 63 and max nesting depth of 7 indicate a dense decision tree that mirrors the breadth of the DOM API it must cover. Like diff, it is in the ‘fire’ quadrant with a recent commit activity of 15.15, so structural complexity and active change are compounding each other in the same file right now.
Recommendation: Consider extracting attribute-diffing and child-diffing logic into dedicated functions; the fan-out of 11 distinct callees suggests natural seam points already exist that could be formalized into smaller, independently testable units.
handleDomVNode — compat/src/render.js
Located in Preact’s React-compatibility layer, handleDomVNode likely mediates between React-style vnode representations and Preact’s internal rendering path — a translation layer that must accommodate the full surface area of React’s DOM API. Its cyclomatic complexity of 45 and max nesting depth of 10 (matching the anonymous fixture function for the deepest nesting in the dataset) signal deeply conditional logic that is hard to reason about or test exhaustively. It is in the ‘fire’ quadrant with a recent commit activity of 14.84, meaning compat-layer changes are actively adding to an already high structural load.
Recommendation: Audit the 12 distinct callees (fan-out of 12) to identify which branches handle distinct React API surface areas — SVG, portals, refs, event normalization — and extract each into a focused handler to reduce both nesting depth and cyclomatic complexity.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
complex_branching | 9 |
long_function | 9 |
deeply_nested | 8 |
god_function | 8 |
exit_heavy | 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
- The
difffunction insrc/diff/index.jshas a cyclomatic complexity of 76 and a recent commit activity of 17.35 — add characterization tests covering its 76 execution paths before the next feature lands in that file. - Both
diffanddiffElementNodesare ‘fire’-quadrant functions in the same file; coordinating refactoring across them together (rather than in isolation) will reduce the risk of introducing inconsistencies in the reconciler. handleDomVNodeincompat/src/render.jshas a nesting depth of 10 — the deepest in production code — and is actively changing; flattening it via dedicated per-concern handlers will make the compat layer safer to extend as React’s API continues to evolve.
Reproduce This Analysis
git clone https://github.com/preactjs/preact
cd preact
git checkout 21dd6d04c1a9a43e5b60976bb5eb7d856253195b
hotspots analyze . --mode snapshot --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 →