What it measures

Custom Hook Cohesion (CHC) is the functional-programming equivalent of Tight Class Cohesion. Instead of class methods sharing fields, a custom hook's return values should share internal state variables.

A hook with CHC = 1.0 is perfectly focused — all its return values relate to the same internal state. A hook with CHC = 0.0 is bundling unrelated concerns and should be split into smaller hooks.

How it's computed

Internal state = variables from useState, useRef, useReducer, useMemo, useCallback.

Two return values are connected if they both reference at least one common internal state variable.

CHC = connected_return_pairs / total_possible_pairs Special cases: 0 or 1 return value → CHC = 1.0 (vacuously cohesive)

Examples

TypeScript — CHC = 1.0 (focused hook)
function useCounter(initial = 0) {
  const [count, setCount] = useState(initial);
  const increment = () => setCount(c => c + 1);
  const decrement = () => setCount(c => c - 1);
  return { count, increment, decrement };
  // all 3 values share `count` state → CHC = 1.0
}
TypeScript — CHC = 0.0 (should be split)
function useUserAndTheme() {
  const [user, setUser] = useState(null);
  const [theme, setTheme] = useState("light");
  return { user, setUser, theme, setTheme };
  // user/setUser share `user`; theme/setTheme share `theme`
  // but no pair crosses both → CHC = 0.0
}
Fix: Split useUserAndTheme into useUser and useTheme. Each will have CHC = 1.0.
Edit on GitHub