Abstracting too early freezes the wrong structure
Aliases: wrong joints · accidental structure · freeze too soon
What it is
The first two call sites often share accidents, not duties: this page’s padding, this API’s field names, the way one designer happened to section the block. Lifting those accidents into a component announces “these seams are the real seams”. When a third and fourth site seam elsewhere, they must warp to fit the structure already in the library, or tear the component open. Premature abstraction freezes joints that are still moving. It is not a name gone generic, and it is not an extra layer of indirection — it happens at the moment the joints are misread.
Abstraction is a bet that the current cut will repeat. With too few call sites, the sample for that bet is too small.
Why it happens
Once a structure enters the shared library, the cost of changing it jumps from “edit two pages” to “edit every caller plus a migration”. That asymmetry lets wrong joints outlive right ones: even after the cut is known to be wrong, the bias is to add a parameter or a special case rather than recut, because recutting startles callers already bound. Accidents get encoded in concrete ways: two surfaces put actions at top-right, so you mint “top-right action bar”; the third surface’s actions belong on each row. What landed is a position, not a duty. Position is an accident of this layout pass; duty might be stable. Premature abstraction writes the accident into the interface, and the interface ships the accident to everyone after. Later callers, trying to “use the system”, keep stuffing the wrong structure, and usage cements the error.
Where it stops holding
Platform primitives (button, text field) already have joints nailed down by the OS and the web; there is no sample problem of “wait for two more products”. Early abstraction there is following an existing contract. A legally frozen flow (one disclosure dialog, nationwide) is already immovable at the second site; waiting for a third is fake waiting. Conversely, during a visual exploration week, while the brand is unfinal and IA is still moving navigation, any library landing is early — repetition then is among comps, not among production duties. Reading “too early” as “never abstract” is also wrong; once joints stabilize, keeping two copies is a different bill. A stability signal: new callers start fitting the existing cut instead of demanding a new axis.
Applying it
- Before promotion, write the candidate’s seams: which parts are duty, which parts are only the first two sites happening to match. Accidents do not enter public props or slots.
- Pieces serving one or two sites while IA is still moving stay as local implementations in the product repo. Ban “we will reuse this later” as a reason to land them.
- When a caller branches around the component’s main structure, suspect a wrong joint first, not “we need another switch”.
- Check: pick a shared component, list its public seams, and list the real duty boundaries of its last three call sites. If one site’s main boundary sits outside the seams and was forced in through props, the wrong structure is already frozen. Ask the author “strip the first two sites’ padding and field names — what is left?”. If what remains cannot be named, the abstraction was early: demote it or recut on the real duty, rather than extending its life with more parameters.
Related
- Same group: R1.08.2 A component with too many parameters cannot be used correctly · R1.08.3 Wait for three repetitions before abstracting — a heuristic, not a law
- Adjacent: R1.17 Over-abstraction of components · R1.02 Component libraries and variants
- Search terms:
premature abstraction·wrong joints·accidental sharing