The pitch for a studio is that the second product is cheaper than the first. It is easy to say and it is only true if you were disciplined about what you built the first time. Here is the actual accounting from our two sports products.

What transferred cleanly

The rendering service

Both apps take a short clip from a phone camera and return that same clip with a tracked pose overlay burned onto it. That is a real video job: decode, run pose estimation per frame, draw, re-encode, upload, and hand back a URL, all inside a window short enough that a user waiting on their phone does not give up.

None of that cares which sport it is. The service that does it for disc golf does it for pickleball unchanged, and because both products share it, each one's traffic keeps the containers warm for the other. That is a benefit neither product could have bought alone.

The commercial rails

Authentication, subscriptions, receipt validation, the webhook that reconciles store events against our own records, attribution, and the release pipeline. This is the least interesting code in the company and it took the longest to get right, which is exactly why reusing it is the highest-leverage thing a studio does.

The specific value is not the code. It is knowing which of these things fail silently. A subscription that attaches to an anonymous identifier instead of the signed-in account looks fine in testing and produces a support ticket a month later from a paying customer who cannot access what they paid for. You learn that once.

The shape of the output

Both products return the same four sections: what is working, the main issues, the fix, and a suggested drill. That contract is enforced on both sides, so the app never renders an empty panel because a model decided to be creative with its formatting.

What did not transfer

More than we expected, and the failures were more instructive than the reuse.

The domain knowledge, obviously

A disc golf backhand and a pickleball drive are both rotational, both depend on bracing against a front leg, and are otherwise unrelated. The analysis instructions had to be written from scratch, by someone who understood the sport, and validated against real footage. This is the part that should be expensive, and it was.

Every string that mentions the sport

When you clone a working product you inherit its vocabulary. An audit of the pickleball app against its parent found that roughly half the user-facing strings were identical, which was mostly harmless boilerplate. Four of them named the wrong sport, and one of those four was the empty state on the history screen: the single string that every new user and every app reviewer sees.

There is no clever fix for this. You read every string.

Model availability

The most annoying discovery of the port. The parent app called a model version that worked fine on its API key and returned a hard error on the newer one, because access to that model generation was tied to when the key was created. Identical code, identical call, different outcome, and no way to reason it out from the error message.

The lesson generalizes past this one vendor: anything provisioned per project is a boundary your reuse does not cross, and it will not announce itself. Now every model call walks a chain and reports every failure in the chain rather than the last one.

The honest number

The second sports product took a small fraction of the first one's calendar time, and effectively all of the remaining work was domain content, copy, and store presence. The infrastructure was close to free. The judgment was not, and never will be.

Reuse buys you the pipeline. It does not buy you knowing what the pipeline should say.