Across the 53 repositories I’ve analysed with Hotspots, one pattern is conspicuously absent from Go, Rust, Python, and Java repos: hub_function. It appears in just 5 repos — and all 5 are TypeScript projects, all building UI frameworks, component libraries, or browser-based applications.
This isn’t a coincidence. It reflects a structural difference in how UI framework code is organised, and it has a specific implication for how those codebases should be refactored.
Hub Functions in the Corpus
| Repo | Hub function | Fan-out | CC | Role |
|---|---|---|---|---|
xyflow/xyflow | useReactFlow | 37 | 16 | Primary public API hook |
react-hook-form/react-hook-form | useFieldArray | 52 | 28 | Array field coordinator |
react-hook-form/react-hook-form | createFormControl | 112 | 174 | Form instance factory |
tldraw/tldraw | putContentOntoCurrentPage | 51 | 36 | Central editor content API |
umami-software/umami | <anonymous> in tracker/index.js | 42 | 32 | Analytics event coordinator |
vadimdemedes/ink | App | 47 | 10 | Terminal UI root component |
A few things stand out. First, the fan-out values are large — 37 to 112 distinct callees from a single function. Second, several of these functions have moderate cyclomatic complexity relative to their fan-out: useReactFlow has CC 16, and ink’s App has CC 10. They are not complex decision-makers. They are connectors.
That’s the defining characteristic of a hub function: high fan-out without proportionally high branching. The function’s risk profile comes from its dependencies, not its own logic.
Why UI Framework Code Produces Hub Functions
React’s programming model creates pressure toward coordinator functions that other paradigms don’t.
A React hook that exposes a library’s public API must aggregate capabilities from across the codebase into a single import. useReactFlow in xyflow is the function every consumer calls — it needs to expose viewport controls, node manipulation, edge management, and selection state. It could split those into domain-specific hooks, but offering one unified hook is a deliberate API choice that concentrates fan-out.
The same pressure applies to the form control factory (createFormControl in react-hook-form), the root component (App in ink), and the central editor API (putContentOntoCurrentPage in tldraw). Each exists because the framework needs a binding point that knows about everything. Over time, as the framework grows, these binding points accumulate more and more callees.
In contrast, Go CLI tools like schollz/croc use sequential pipelines where each step (Send, receive, processMessageFileInfo) handles a bounded stage. No function needs to aggregate the full API surface. The same is true for Rust systems code: ownership rules actively discourage the shared-mutable-state patterns that produce high fan-out coupling, and the ecosystem doesn’t have a “primary hook” convention.
The Risk Profile Is Different from a God Function
A hub function with moderate CC but high fan-out is a different kind of risk than a god function with high CC and high fan-out.
A god function is brittle because of its own internal complexity — there are many paths through it, any of which can break when the function is modified. The danger is internal.
A hub function (in the pure case, low CC / high FO) is brittle because of its dependencies — every callee is a potential source of interface changes that require the hub to update. A callee that changes its signature, its error behaviour, or its return type creates a change requirement in the hub. With 50+ callees, the probability of a callee changing in any given development cycle approaches 1. The danger is external.
This distinction matters for refactoring strategy:
- For a god function, the intervention is decomposition: extract internal logic into named sub-functions to reduce CC.
- For a hub function, the intervention is layering: introduce intermediate collaborators that own a bounded slice of the callees, so the hub delegates to a small number of well-scoped objects rather than 50+ individual functions.
useReactFlow doesn’t need to be decomposed — its logic is already flat. It needs its 37 callees grouped into 3–4 domain objects (viewport, nodes, edges, selection) that the hook composes. The fan-out from useReactFlow drops to 4; the domain objects absorb the rest.
The Exception: createFormControl
createFormControl in react-hook-form is both a hub function and a god function — CC 174 and FO 112 simultaneously. This is the worst-case combination: the function has extreme internal complexity and extreme external coupling. It is flagged with both patterns.
In these cases, the refactoring is harder because both internal and external problems need to be addressed, and they interact. Extracting logic from createFormControl into sub-functions is correct, but those sub-functions will themselves inherit some of the fan-out. The right sequence is to stabilise the callee interfaces first (reduce the churn sources), then decompose the internal logic once the dependency surface is predictable.
What to Watch For
If you’re building a TypeScript UI library or framework, hub functions will appear — some are inevitable and intentional. The signal that one has crossed from deliberate to problematic:
- It appears in your top-5 risk functions by activity-weighted score (meaning it’s being actively changed while already broadly coupled)
- Its fan-out has grown past the scope of its stated purpose — it’s reached into subsystems that aren’t really its responsibility
- A change in a single callee triggers a cascade of changes in the hub
At that point, the intervention is layering, not deletion. The hub should still exist; it should just delegate to well-scoped collaborators instead of reaching directly across the codebase.
This analysis covers 53 open-source repositories analysed with Hotspots between March and April 2026. Hub function data reflects the top-5 hotspot functions per repo as scored by activity-weighted risk. Part of a series: five patterns in TypeScript OSS repos and why TypeScript produces less exit-heavy code and more branching than other languages.
Hotspots highlights structural and activity risk — not “bad code.” Editorial policy →