From prototype to production — when (and how) to rewrite vibe-coded code
How to tell when your weekend prototype has outgrown itself, and how to harden it without throwing the whole thing away.
Vibe-coded apps have a moment. The prototype that took an afternoon now has real users, real bugs, and a feature backlog. The instinct is to rewrite the whole thing properly. That is usually the wrong call.
Here is a more useful frame for the prototype-to-production transition.
The prototype was not bad code
It was appropriate code. A prototype is meant to test a question: "Does anyone want this?" Once the answer is yes, the requirements change — but that does not retroactively make the prototype shameful. It made the rewrite possible.
Treat the prototype as a working spec, not as a mistake.
Rewrite the parts under load, keep the parts that work
Most prototypes have a few hot spots and a lot of cold code. The hot spots are where the rewrite happens; the cold code can ride along untouched for a long time.
A useful sequence:
- Add monitoring before changing anything. You cannot prioritize rewrites if you do not know where the pain is. Errors, slow endpoints, expensive queries.
- Stabilize the boundary first. Auth, payments, anything where wrong = bad. Tighten types, add tests, narrow inputs.
- Rewrite one feature at a time. Pick the noisiest feature in your monitoring. Rewrite it. Ship. Watch. Move to the next.
- Leave the cold code alone. That admin page nobody uses does not need a refactor today.
The point is: rewrite by feature, not by codebase.
The signs you actually do need a fuller rewrite
A targeted rewrite is the default; a full rewrite is occasionally warranted. Signs you are in the second case:
- You cannot make any change without breaking three other things.
- The framework or runtime is no longer maintained.
- The shape of the data model is fundamentally wrong for what the app is becoming.
- You have to onboard another person and the codebase is impossible to explain.
If only one of these is true, do the targeted rewrite. If three are true, you might genuinely be better off starting fresh — with the prototype open in another window the whole time.
Production checklist for code that started as a prototype
Once a feature is being rewritten for production, this is the minimum bar:
- Real error handling. No silent catches. Errors get logged with context.
- Real types. Get rid of
any. Narrow what comes in from external sources. - Tests on the boundary. End-to-end for the happy path, unit tests for the parts that handle money or auth.
- A migration plan if the data model is changing. Backups first. Migrations are reversible. New code reads both old and new shapes during the transition.
- A feature flag if the change is risky. Roll out to ten percent first.
This is not "production-grade for a 500-person company." It is "production-grade for a real app with real users." You do not need more than this until your scale is asking for it.
The mindset shift
Vibe coding the prototype was a sprint. The transition to production is a different muscle — slower, more deliberate, more conservative. The tools are the same, the speed is not.
That shift is fine. Notice when you are in production mode and let yourself slow down. The model is still helping; you are just asking it different questions: "Find every place that handles user input without validation," not "Build me a feature in twenty minutes."
If your app has real users now, the ship checklist is the right next read.