ref-patterns

Installation
SKILL.md

Ref Patterns

Concept of the skill

Ref Patterns is the discipline of choosing, forwarding, and exposing React refs deliberately, with a single sharp rule at its center: refs are the intentional hole in React's "UI is a pure function of state and props" contract. A ref is a mutable container — { current: T } — that React creates once per component instance and preserves across renders; writing to ref.current does not trigger a re-render and reading from it does not subscribe the component to changes, so the ref lives entirely outside the reactive graph. That escape-hatch nature makes refs right for exactly two families of values — a stable handle to a DOM node (for focus, measurement, animation, or handoff to a non-React library) and a mutable instance value the component needs but should not render (an interval id, a requestAnimationFrame id, a latest-arguments closure, a previous-value snapshot) — and wrong everywhere else, because a ref used as a substitute for state silently breaks the contract: the value changes, the UI does not update, and the bug surfaces remote from its cause. On top of the useRef primitive sit four layered mechanics this skill owns end to end: ref callbacks for synchronous mount/unmount hooks and ref composition, forwardRef (React 18 and earlier) and the React 19 ref-as-prop change that retires it for new code, useImperativeHandle for exposing a minimal controlled imperative surface to a parent, and the requirement that every compound-component primitive forward refs through to its underlying DOM element. It deliberately does not own the broader hook discipline (hooks-patterns), state location and ownership (state-management), the client/server serialization boundary (client-server-boundary), cross-product component layering (component-architecture), or form-state design (form-ux-architecture) — it owns the not-state primitive and the sharp decision boundary between a ref and state.

Coverage

The discipline of designing React ref usage: the conceptual distinction between refs (mutable handles that survive renders without triggering them) and state (reactive values that do trigger renders), the useRef hook for DOM access and mutable instance values, ref callbacks (ref={(node) => ...}) for fine-grained mount and unmount hooks, forwardRef for passing refs through component boundaries on React 18 and earlier, the React 19 ref-as-prop change that retires forwardRef for new code, useImperativeHandle for exposing a controlled imperative surface to a parent ref, the ref-forwarding pattern used inside compound-component primitives (Radix Slot / Headless UI), and the central design rule that refs are an escape hatch — appropriate for DOM access, focus management, animation, measurement, integration with non-React DOM libraries, and sparingly-exposed imperative APIs — never as a substitute for state.

Philosophy of the skill

React's rendering model is built on a single contract: the UI is a pure function of state and props. When state changes, the component re-renders; the new output is reconciled against the old; the DOM updates. This contract is what makes React components composable, testable, and reasonable.

Refs are the deliberate hole in that contract.

A ref is a mutable container — { current: T } — that React creates once per component instance and preserves across renders. Writes to ref.current do not trigger a re-render. Reads from ref.current do not subscribe to changes. The ref exists outside the reactive graph.

That's exactly what makes refs useful in the few places they belong:

Installs
1
GitHub Stars
1
First Seen
Jun 18, 2026
ref-patterns — jacob-balslev/skill-graph