At commit be39702, Hotspots surfaces two critical-band functions in twentyhq/twenty that combine high structural complexity with recent commit activity — each touched within the last three days, each carrying an activity-weighted risk score above 19. Twenty is an open-source CRM platform with 16,560 analyzed functions, 647 of which rank as critical. The top two functions — recalc in the xlsx sandbox script and HalftoneCanvas in the website renderer — both land in the “fire” quadrant, meaning they are simultaneously hard to reason about and actively changing right now, not problems deferred to a future sprint.
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 |
|---|---|---|---|---|---|
recalc | packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/xlsx/recalc.py | 19.0 | 51 | 7 | 16 |
HalftoneCanvas | packages/twenty-website/src/lib/halftone/components/HalftoneCanvas.tsx | 19.0 | 43 | 6 | 140 |
HalftoneStudio | packages/twenty-website/src/app/[locale]/halftone/_components/HalftoneStudio.tsx | 17.4 | 24 | 5 | 81 |
validate_all_relationship_ids | packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/docx/validation/base.py | 17.4 | 40 | 7 | 21 |
apply_replacements | packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/pptx/replace.py | 17.3 | 54 | 4 | 32 |
Large Repo Analysis
twenty 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.
The headline numbers tell a clear story: both top-ranked functions carry activity-weighted risk scores above 19.0, flag every structural antipattern in the dataset — complex branching, deep nesting, god-function coupling, multiple exit paths, and excessive length — and were each modified within the last 72 hours. That combination is the definition of live regression risk.
recalc — packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/xlsx/recalc.py
With a cyclomatic complexity of 51 and a max nesting depth of 7, recalc is the most structurally dense function in this hotspot set, carrying an activity-weighted risk score of 19.01. Its file path places it inside a sandboxed code-interpreter module responsible for processing xlsx data — a context where correctness is non-negotiable and edge cases proliferate. CC 51 means there are at least 51 independent execution paths through this function; each one is a required test case and a potential bug surface. Nesting reaching level 7 means a developer reasoning about the deepest conditional must mentally track seven layers of context simultaneously — well past the ND 4 threshold that reliably signals comprehension difficulty.
The god-function and long-function patterns compound the branching problem: recalc calls into 16 distinct functions (fan-out of 16) while also inlining what are likely several discrete logical stages of recalculation. Exit-heavy behavior — multiple return or exception paths scattered across 51 branches — makes exhaustive test coverage genuinely difficult to achieve and verify. The function was touched once in the last 30 days, just three days ago, confirming it is under active development. The file has no historical bug-linked commits or reverts recorded, which is useful context: the risk here is structural and forward-looking, not a record of past failures. The single author active in the last 90 days means there is concentrated ownership — a bus-factor concern if this module needs urgent attention from others.
Recommendation: Apply extract-method refactoring to decompose recalc into named sub-functions that each handle one recalculation stage. Targeting the deepest nesting clusters first — those contributing most to the ND 7 score — will yield the fastest comprehension improvement. Aim to bring CC below 20 across the resulting functions, which would also make each branch testable in isolation.
HalftoneCanvas — packages/twenty-website/src/lib/halftone/components/HalftoneCanvas.tsx
HalftoneCanvas is the most structurally coupled function in this analysis. It calls into 140 distinct functions — a fan-out figure that is not a typo — making it the structural centre of gravity for the halftone rendering subsystem in Twenty’s marketing website. A change anywhere in those 140 callees can have an unexpected effect on this component, and a change inside HalftoneCanvas itself ripples outward just as broadly. Its cyclomatic complexity of 43 and nesting depth of 6 indicate that the component has accumulated significant conditional rendering logic, likely handling canvas API calls, animation frame management, device pixel ratio calculations, and responsive layout decisions all within one function body.
Like recalc, it was touched once in the last 30 days — three days ago — and sits firmly in the “fire” quadrant with an activity-weighted risk score of 19.0. The exit-heavy pattern suggests multiple early-return guards (perhaps for null canvas refs, missing browser APIs, or SSR environments), each of which is a path that must be independently exercised by tests. With a single author active in the last 90 days and no prior bug or revert history on file, the concern is purely structural: a component this large and this broadly coupled becomes increasingly fragile with each iteration.
Recommendation: Introduce a facade or decompose HalftoneCanvas into focused sub-components or custom hooks — for example, separating canvas initialization, the render loop, and event handling into distinct units. Reducing fan-out from 140 to something closer to 20–30 per sub-unit would make individual behaviors testable without instantiating the entire rendering pipeline.
HalftoneStudio — packages/twenty-website/src/app/[locale]/halftone/_components/HalftoneStudio.tsx
HalftoneStudio is the companion hotspot to HalftoneCanvas: lower on raw branching than the renderer, but still broad enough to make UI changes expensive. Its activity-weighted risk score of 17.4 comes from CC 24, nesting depth 5, and fan-out 81, which points to a component coordinating many behaviours rather than only presenting state. Because it lives in the app-level halftone route, it likely owns configuration, preview state, and wiring into the canvas component.
The right move is to split orchestration from presentation. Extract custom hooks for studio state and controls, then leave the component to compose smaller pieces. That would reduce the god-function and long-function pressure while giving tests stable seams around the most change-prone UI decisions.
validate_all_relationship_ids — packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/docx/validation/base.py
The DOCX validator shows the same sandbox-script pattern as recalc, but in validation rather than spreadsheet recalculation. CC 40 and nesting depth 7 are enough to make invalid-document edge cases hard to audit, and the risk score of 17.4 keeps it close behind the halftone UI functions. Fan-out is a more contained 21, so the main issue is not call breadth; it is deeply nested decision logic.
Start by flattening guard clauses and extracting validators for each relationship category. A validation pipeline with named checks would make the exit-heavy paths explicit and would let tests target one document relationship rule at a time instead of exercising the whole validator.
apply_replacements — packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/pptx/replace.py
apply_replacements has the highest CC in the top five at 54, but its lower nesting depth of 4 keeps it just below the other sandbox functions with a 17.3 risk score. That shape suggests many replacement cases or type-specific branches arranged relatively flatly. The fan-out of 32 also indicates a function doing substantial orchestration across the PPTX replacement pipeline.
Prioritise a dispatch-table or strategy-style split by replacement type. That would turn the broad branch set into named handlers, reduce the parent function’s CC, and make regressions easier to isolate when presentation replacement behaviour changes.
Key Takeaways
recalcneeds decomposition now. CC 51 with nesting depth 7 in an actively-changing sandbox script is the highest-priority refactoring target in this analysis. Extract discrete recalculation stages into named functions before the next development push adds more branching.HalftoneCanvas’s fan-out of 140 is the broadest coupling in the dataset. Even incremental decomposition — extracting the render loop or initialization logic into a custom hook — would meaningfully reduce the blast radius of future changes.- The sandbox scripts repeat the same shape across formats.
validate_all_relationship_idsandapply_replacementsshould be split into named validators or replacement handlers so edge cases can be tested independently.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
complex_branching | 5 |
god_function | 5 |
long_function | 5 |
deeply_nested | 4 |
exit_heavy | 4 |
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/twentyhq/twenty
cd twenty
git checkout be39702fd2fbbd303af5d85ddc8624228ae4cf9c
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 →