At commit 155fa13, the highest activity-weighted risk in chakra-ui doesn’t live in the core styled-system or component primitives — it lives in the codemod tooling. collectChakraLocalNames in packages/codemod/src/utils/chakra-tracker.ts carries an activity-weighted risk score of 20.63, the top score in the repo, with a cyclomatic complexity of 38 and 1 commit touch in the last 30 days — making it a live regression risk, not merely a cleanup item. Across 3,043 analyzed functions, 96 reach the critical band; both top-ranked functions are in the codemod package and are classified as “fire” quadrant, meaning they are structurally complex and actively changing right now.
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 |
|---|---|---|---|---|---|
collectChakraLocalNames | packages/codemod/src/utils/chakra-tracker.ts | 20.6 | 38 | 6 | 12 |
transformer | packages/codemod/src/transforms/components/button.ts | 17.5 | 48 | 6 | 22 |
transformer | packages/codemod/src/transforms/theme/theme-tokens.ts | 17.5 | 44 | 5 | 77 |
transformer | packages/codemod/src/transforms/components/pin-input.ts | 17.2 | 28 | 6 | 36 |
transformer | packages/codemod/src/transforms/components/number-input.ts | 16.0 | 27 | 5 | 25 |
Large Repo Analysis
chakra-ui is a large repository. To stay within memory constraints, this analysis used hybrid touch mode: structural complexity — CC, ND, FO — is measured precisely for every function. Git activity is tracked at the function level (via git log -L) only for files with 5 or more commits in the last 30 days; other files use a file-level approximation. Rankings therefore surface functions that are both structurally complex and in the most actively-changing parts of the codebase. Dormant code with high structural complexity will rank lower than it would under a full per-function analysis — to surface it, run hotspots analyze . --per-function-touches on a machine with sufficient memory.
Codemod / Tooling Files in Results
All five of the top-ranked functions live in packages/codemod, a code-transformation tooling package rather than the runtime React component library. Codemod tooling is intentionally complex because it handles AST traversal and migration transforms, and its risk scores reflect that domain complexity rather than product code maintainability. If you want to focus hotspots analysis on the runtime library only, add the following exclude pattern to your .hotspotsrc.json: { "exclude": ["packages/codemod/"] }.
The risk profile for chakra-ui at this snapshot is concentrated rather than spread out. Of the 96 critical-band functions, the two highest scorers share a home: the packages/codemod package. Both carry the full suite of structural antipatterns — complex branching, deep nesting, multiple exit paths, god-function coupling, and excessive length — and both were touched within the last 29 days. That combination is what pushes them into the “fire” quadrant and makes them worth addressing before the codemod tooling ships to consumers.
collectChakraLocalNames — packages/codemod/src/utils/chakra-tracker.ts
This is the structural centre of gravity for the codemod package. With a fan-out of 12 distinct callees, collectChakraLocalNames reaches broadly across the codemod utility layer — changes to its call contract ripple outward to every consumer that depends on accurately resolved Chakra import names. The name suggests it walks an AST or module graph to collect local binding names for Chakra-UI symbols, a task that inherently branches on import styles, aliasing, re-exports, and namespace patterns.
The metrics tell a pointed story. A cyclomatic complexity of 38 means 38 independent execution paths through a single function — each path is a required test case and a potential regression surface. A max nesting depth of 6 compounds that: reasoning about the outermost branches requires holding six levels of context simultaneously, well past the ND 4+ threshold that signals readability breakdown. The function also flags as exit_heavy, meaning multiple return paths are scattered through those nested branches, which raises the cost of achieving meaningful test coverage. With 1 commit touch in the last 30 days (29 days ago), this is not dormant legacy code — it is actively changing.
The external signals here are sparse: one total commit, one author in the last 90 days, no bug-linked commits or reverts. That absence of historical defect signal is worth noting — the risk is structural, not an established bug history. But a single-author, high-complexity function with active churn is a knowledge-concentration risk: if that author is unavailable when a regression surfaces, the blast radius is high and the debugging surface is enormous.
Recommendation: Apply extract-method refactoring to decompose collectChakraLocalNames by import pattern type — one handler per recognized import shape (named imports, namespace imports, aliased re-exports, etc.). Each extracted function should carry its own unit tests. Targeting a post-refactor CC below 15 per extracted unit is a realistic first milestone and would eliminate the god-function and deeply-nested antipatterns in a single pass.
transformer — packages/codemod/src/transforms/components/button.ts
If collectChakraLocalNames is the highest-risk function by activity-weighted score, transformer is the highest by raw structural complexity. At a cyclomatic complexity of 48 — 10 points above its stablemate — it holds 48 independent execution paths through a single transform function. Its fan-out of 22 is the largest in the top hotspots list, meaning it calls into 22 distinct functions, making it a hub that coordinates the full surface of the Button component migration. Its activity-weighted risk score of 17.53 puts it firmly in the critical band.
Both collectChakraLocalNames and transformer share the same structural antipattern fingerprint: complex branching, deep nesting (ND 6), exit-heavy control flow, god-function coupling, and excessive length. In transformer, the fan-out of 22 is the more alarming signal — a change to any one of those 22 callees, or a new Button prop variant that requires a new branch, forces a developer to navigate a function that already has 48 paths. Like its sibling, the external signals show no prior bug-linked commits or reverts, so the risk is forward-looking: the next change to this function is the one most likely to introduce a regression.
Recommendation: Decompose transformer by migration concern. A codemod transformer for a single component should not need CC 48; that complexity suggests it is handling prop renaming, variant mapping, size normalization, and possibly JSX restructuring all in one body. Splitting those concerns into focused sub-transformers — each testable in isolation — would reduce fan-out to a coordination layer and bring individual path counts into a range where coverage is achievable.
transformer — packages/codemod/src/transforms/theme/theme-tokens.ts
The third-ranked function shares an activity-weighted score of 17.5 with the button transformer and is structurally distinct in one key way: a fan-out of 77 — more than three times the next highest in the top five. Where transformer in button.ts is a hub by virtue of coordination complexity, this function calls into 77 distinct callees, making it the broadest dependency surface in the critical band. Its cyclomatic complexity of 44 and max nesting depth of 5 confirm the full antipattern suite: complex branching, deep nesting, exit-heavy control flow, god-function coupling, and excessive length.
Recommendation: Prioritize extracting the fan-out before addressing the branching. At FO 77, the first step is identifying which callees belong to coherent theme-token concerns (color, typography, spacing, etc.) and grouping them behind dedicated sub-transformer functions. Reducing the coordination surface will make the remaining branching complexity tractable.
transformer — packages/codemod/src/transforms/components/pin-input.ts
Fourth by risk score at 17.2, the pin-input transformer has CC 28, ND 6, and FO 36. Its nesting depth matches the button transformer’s ND 6 — the deepest in the top five — and its fan-out of 36 places it as the second broadest callee surface. Like the other codemod transformers, it carries the full structural antipattern fingerprint and was active within the same recent commit window. Its lower CC (28 vs. 48 in button.ts) reflects a narrower migration surface, but ND 6 still means six levels of nested context to hold while reasoning about any branch.
Recommendation: Apply the same decompose-by-concern approach as the button transformer: identify each distinct prop migration (renaming, event handler changes, slot restructuring) and extract it into a named sub-transformer. Each extracted unit should have ND ≤ 3 as a post-refactor target.
transformer — packages/codemod/src/transforms/components/number-input.ts
The fifth function rounds out a pattern that is consistent across all four codemod transformers: CC 27, ND 5, FO 25, activity-weighted risk 16.0. Its structural profile is the most moderate in the top five, but it still carries the full antipattern set. Given the repetition of function name and file structure across the codemod package, these four transformers are strong candidates for a shared refactoring pass — a common sub-transformer interface would allow each to delegate to focused concern handlers while keeping the coordination logic thin and independently testable.
Key Takeaways
- Decompose
collectChakraLocalNamesfirst. With an activity-weighted risk score of 20.63, CC 38, ND 6, and a commit touch 29 days ago, it is the single highest-priority refactoring target in the repo. Extract per-import-pattern handlers, each with independent tests, to bring CC below 15 per unit. - Audit
transformerbefore the next codemod release. CC 48 and FO 22 in a single Button transform function means 48 paths through a 22-callee hub — the next prop addition or variant change runs a high regression risk. Decompose by migration concern before expanding coverage. - The codemod package is the active risk zone, not the core React layer. All five hotspots are transformer functions in
packages/codemod. Structural debt is concentrated in tooling, not in the component primitives consumers depend on. A shared decompose-by-concern refactoring pass across the fourtransformerfunctions would address the pattern systematically.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
complex_branching | 5 |
deeply_nested | 5 |
exit_heavy | 5 |
god_function | 5 |
long_function | 5 |
hub_function | 1 |
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.
Reproduce This Analysis
git clone https://github.com/chakra-ui/chakra-ui
cd chakra-ui
git checkout 155fa1388825debedcf2017b2a51b85d179fc701
hotspots analyze . --mode snapshot --explain-patterns --force --hybrid-touches 5
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 →