How to buy a custom app build without buying the rewrite later

You hired someone to build you a custom app. The build went well. The app shipped. The team felt good about the engagement. Then a year passed. The app needs to extend in ways the original didn't anticipate. You hire someone to extend it. They look at the code, the documentation, the architecture, and tell you the right answer is to rewrite. You've now paid twice for what should have been one investment.

This pattern repeats often enough that it's worth understanding why it happens and how to prevent it. The pattern isn't always the original builder's fault. Sometimes the buyer didn't specify what they needed beyond the visible app. Sometimes the engagement was scoped as "build this thing" without the additional discipline that makes the thing extensible. Sometimes the original builder did their job and the rewrite was inevitable because the business pivoted.

The cases where rewriting is genuinely inevitable are rare. Most of the time, the rewrite happens because the original build skipped specific things that would have preserved extensibility. Those things are nameable, contractable, and verifiable. You can buy a custom build that doesn't set up the rewrite, but only if you demand specific deliverables that most engagements don't include by default.

I want to walk through the four common failure modes and the contract-level discipline that prevents each.

Failure mode one: no specification document

The buyer described what they wanted. The builder built something matching the description. The description wasn't preserved in any structured way. A year later, the new team has the code but not the original intent. They can't tell which features were core, which were experimental, which were workarounds, which were load-bearing.

The contract demand that prevents this: a specification document delivered as part of the build, kept current as the build evolves, handed over with the code. The document captures what the app is, who it's for, what assumptions the architecture makes, what each major component does, what counts as success.

This isn't optional documentation. It's the artifact that makes the app extensible. Without it, the next team is reverse-engineering intent from implementation, which is much more expensive than writing the implementation against captured intent.

Most build engagements don't include this by default. Most rewrites that follow those engagements happen because of its absence.

Failure mode two: no decision log

Every architectural decision in the build had alternatives. The builder chose this stack over others. This data model over others. This integration approach over others. The reasoning behind each choice isn't preserved. The new team sees the choices and can't tell whether they were deliberate (matching real constraints) or arbitrary (the builder's default).

The contract demand: a decision log capturing the major architectural decisions with the reasoning behind each. Why this stack. Why this database. Why this vendor for payments. Why this approach to authentication. Why we explicitly chose NOT to use this otherwise-obvious alternative.

The decision log is the artifact that prevents the new team from reversing decisions that had good reasons (and rediscovering the problems those decisions prevented). It also gives them confidence to change decisions that no longer fit, because they know what considerations the original decision was responding to.

A decision log is cheap to maintain during the build (write an entry when a decision is made). It's expensive to reconstruct after the fact (the original team's reasoning is partly lost; some has to be guessed).

Failure mode three: no runbook

The original builder knew how to deploy the app, where the logs were, what to check when something broke, which monitoring alerts mattered. None of this lives in the codebase. By handoff time, much of it lives only in the original builder's heads. The new team has to rebuild operational knowledge through trial and error.

Each operational lesson learned the hard way is an incident. Incidents cost users, money, and trust. The cumulative cost of operational knowledge rebuilding can exceed the cost of the original build.

The contract demand: a runbook delivered with the build. Covers deployment, log access, common incident response, vendor contacts, credential management, monitoring interpretation, data recovery procedures. The runbook is what makes the app operable by the next team without recreating the operational knowledge through suffering.

The full pattern for handoff readiness is covered in hand off a custom app without inheriting brittleness debt. The short version: if the original build doesn't ship with a spec, a decision log, a runbook, and observable architecture, the next team will spend more rebuilding context than the original build cost to write.

Failure mode four: no observability surface

The original build either has minimal observability (logs that only the original builder can interpret) or none at all (the team finds out about problems from user complaints). The new team can't extend safely because they can't tell what's currently working, what's broken, what their changes are doing.

Adding observability after the fact is much more expensive than building it in. The new team often spends weeks instrumenting the existing app before they can confidently make changes. That time is paid by you, not by the original builder.

The contract demand: the build includes observability appropriate to the app's stakes. Structured logging. Error tracking. Health endpoints. Monitoring dashboards. Alert configurations. The contract should specify what gets monitored and what alerts fire on what conditions.

This isn't engineering overhead; it's the difference between an app the next team can run and an app they can't.

The contract structure that prevents the rewrite

When buying a custom build, the contract should specify deliverables beyond just "working application." The deliverables that matter for preventing the rewrite:

Code that passes a defined set of quality bars. Tests, linting, type-checking, build pipeline that produces deployable artifacts. The quality bars should be enumerated, not implied.

Documentation set: specification document, decision log, runbook. Each one delivered, current, and handed over with the code.

Observability surface: structured logs, error tracking, health endpoints, monitoring configuration. The surface should be operational at handoff, not just specified for future implementation.

Handoff process: a defined period where the original builder is available to answer questions, walk the new team through the architecture, update the documentation based on what's unclear. Not optional; not afterthought.

Migration support: if the build uses any vendor-specific tooling, the contract specifies what would be involved in migrating away from those vendors. The buyer keeps the optionality even if they never use it.

Each of these is a contract addendum, not a code change. The original builder can deliver them as part of the engagement if they're specified upfront. They often won't be delivered if they're not specified, because they're not "the visible app" that the engagement is anchored on.

The service tier structure

When VibeKoded scopes a custom-app engagement, the service tiers reflect this discipline. The smallest tier (scope the build) captures the specification document and the architectural decisions before any code is written. The middle tier (build the prototype) delivers a working MVP with the documentation set and observability built in. The largest tier (ship the production app) delivers the full production-grade system with the full handoff package: tested, observable, documented, runbook'd, ready for the next team.

Each tier produces deliverables that preserve optionality. A buyer can stop at the scope tier and have something they could hand to a different builder. They can stop at the prototype tier and have an extensible MVP. They can complete the production tier and have a system that the next team can extend without rewriting.

The discipline isn't unique to VibeKoded; it's the discipline that should be in every custom-build engagement and isn't in most. The buyer who demands these deliverables and the builder who delivers them produce work that doesn't set up the rewrite.

What to do if you've already paid for a build that doesn't have these

If you're already in the post-build phase and discovering that the original engagement didn't include the spec, the decision log, the runbook, or the observability, the work to add them is bounded but not free. It's typically a focused engagement: a builder reads the existing code, infers as much intent as possible, captures it in the missing artifacts, fills the observability gap.

The cost is real but it's smaller than the rewrite would be. Doing it preserves the existing build's investment and gives you the artifacts the next team will need.

If your situation is "the original build is incomprehensible to the next team and we're considering a rewrite," running the artifact-creation engagement first is often the right move. It either reveals that the existing code is salvageable with documentation (in which case you saved the rewrite cost) or confirms that the rewrite is genuinely needed (in which case you have clearer specification for the rewrite).

The discipline that prevents the rewrite is also the discipline that diagnoses whether the rewrite is necessary when you're past the point of preventing it.


Got a custom-build engagement coming up and want help structuring the contract to prevent the eventual rewrite? Send the app description, the builder you're evaluating, and your durability expectation. VibeKoded can scope the prototype, build the MVP, or hand off the production app. → Work with VibeKoded