Reuse vs Rewrite: When to Share Code Across Products
Reuse vs rewrite is the daily decision behind a compounding foundation. Here is the rule for when to share code across products and when to just copy it.
Reuse when the thing is genuinely the same across products and changes rarely for product-specific reasons. Rewrite, or just copy, when it is superficially similar but pulls in different directions per product. That is the reuse vs rewrite rule, and getting it right is the difference between a foundation that compounds and one that couples every company to every other. Most teams reuse too much and pay for it in coupling, or reuse too little and pay for it in fragmentation. Here is how I draw the line.
Reuse the plumbing that is identical everywhere
Some things are the same in every product, full stop. Authentication. Billing mechanics. Deploy. Logging. The base data layer. Nobody's product is better because its login is bespoke, and the risk of getting these wrong is high, so I want them built once and inherited. This is the core of the shared foundation, and reusing it is pure upside: one implementation to secure, one to patch, one to audit.
The test is whether being different buys the product anything. For plumbing, it never does. Reuse it, put it in the foundation, and let every venture inherit it. That is how you get the compounding described in infrastructure that compounds instead of paying for the same plumbing twenty times.
Rewrite the parts that pull in different directions
The trap is reusing things that only look the same. Two products both have a customer onboarding flow, so it seems reusable. But one is a legal tool and one is a hosting product, and their onboarding needs diverge the moment you look closely. Force them onto shared code and every change one needs risks breaking the other. Now you have coupled two unrelated companies, and both move slower.
When something is product-specific, or when sharing it would couple products that should stay independent, rewrite it or copy it per product. Copy-paste has a bad reputation it half deserves, but two independent copies that can each change freely often beat one shared version that neither product can touch without a cross-product regression sweep. Independence has real value, and coupling has a real cost.
The rule: two cases, and stable
I only move something into the shared foundation when two conditions hold. First, a second product genuinely needs the same thing, not something that rhymes with it. One case is not a pattern; it is a feature of one product. Second, the thing is stable, meaning it does not change for reasons specific to one product. If a shared component keeps needing product-specific tweaks, that is the signal it should never have been shared.
Waiting for the second case kills wrong abstractions before they cost you. The instinct to reuse the first time you see a pattern is exactly the instinct that produces the abstractions everyone later works around, which I covered in the mistakes that turn a foundation into dead weight.
When reuse becomes coupling, split it back out
Reuse is not permanent. Sometimes you share something correctly, and then one product's needs diverge for real. When that happens, split it back out. Give the diverging product its own copy and let the shared version serve the rest. Holding onto a shared component past the point where it fits every consumer is how a foundation slowly turns into a tangle.
The health check is simple: does a change to a shared component regularly require reasoning about specific products? If yes, it is coupling wearing a reuse costume, and it should come apart. A good foundation is mostly things that are stably identical, with the divergent stuff kept per product.
Keep both paths cheap and safe
Whether you reuse or rewrite, the change has to ship safely. Shared changes touch every consumer, so they get a spec, tests, and a scripted migration, run through the same spec-driven development loop I use for everything, with Bootspring turning the spec into a tested increment. Making shared changes safe is what lets me reuse aggressively where it is right, because I am not afraid to touch the core. And I keep the rewritten, per-product code honest on quality with ReformCode, so copy-paste does not quietly rot into unmaintainable divergence.
Reuse the identical plumbing, rewrite the divergent product logic, wait for two stable cases before sharing, and split back out when reuse turns into coupling. Do that and the foundation compounds without gluing your companies together.