The Problem
Your prototype works. Now someone asks: "Can we ship this?" And you freeze.
The code is held together with hope and TODO comments. Shipping feels irresponsible. But rewriting from scratch feels wasteful. You're not sure how to evaluate what you have.
The real question isn't "prototype or production." It's: What parts of this prototype can survive contact with production?
The Core Insight
Not all code needs the same treatment. A prototype has three types of code:
| Category | Description | Action |
|---|---|---|
| Keep | Works correctly, handles edge cases, readable | Ship as-is with minor cleanup |
| Harden | Logic is sound, but needs error handling, tests, or documentation | Add production qualities |
| Rewrite | Fundamentally flawed - wrong approach, security issues, technical debt | Start fresh with lessons learned |
The framework helps you categorize each piece of code and make deliberate decisions.
The Decision Framework
Step 1: Risk Assessment
For each component, ask: What happens if this breaks in production?
Risk Levels
- Low Risk: Users see an error, retry, life goes on (UI glitches, non-critical features)
- Medium Risk: Users lose work or have degraded experience (data display, notifications)
- High Risk: Data loss, security breach, financial impact (auth, payments, data storage)
High-risk code needs hardening or rewrite. Low-risk code might ship as-is.
Step 2: Code Quality Audit
For each component, evaluate:
| Criterion | Prototype Level | Production Level |
|---|---|---|
| Error Handling | Crashes or silent failures | Graceful degradation, user feedback |
| Input Validation | Assumes valid input | Validates and sanitizes all input |
| Edge Cases | Happy path only | Handles nulls, empty, boundaries |
| Tests | None or minimal | Critical paths covered |
| Documentation | Code comments, maybe | API docs, README for maintainers |
| Logging | console.log statements | Structured logging, error tracking |
Step 3: The Decision Matrix
Combine risk level with quality score:
Low Quality Medium Quality High Quality
High Risk REWRITE HARDEN KEEP (review)
Medium Risk HARDEN HARDEN/KEEP KEEP
Low Risk KEEP (maybe) KEEP KEEP
Applying the Framework
Example: E-commerce Checkout Prototype
Let's categorize a prototype checkout flow:
Component: Cart Display
Risk: Low (wrong display, user notices, retries)
Quality: Medium (works, no edge case handling)
Decision: KEEP - add basic null checks
Component: Payment Processing
Risk: High (money involved, security critical)
Quality: Low (happy path only, no validation)
Decision: REWRITE - use established payment library
Component: Order Confirmation Email
Risk: Medium (missed emails = support tickets)
Quality: Medium (works, no retry logic)
Decision: HARDEN - add retry logic and logging
Hardening Checklist
When a component needs hardening (not rewrite), here's what to add:
Minimum Viable Production (MVP)
- Input validation - Validate types, ranges, required fields
- Error handling - Try/catch with meaningful error messages
- Null checks - Handle missing data gracefully
- One test - At least one test for the critical path
- Logging - Log errors with enough context to debug
Full Production
Add to MVP:
- Edge case tests - Empty arrays, null values, boundary conditions
- Documentation - Function signatures, expected behavior
- Metrics - Track usage, errors, performance
- Rate limiting - Prevent abuse (if applicable)
- Graceful degradation - Fallbacks when dependencies fail
Rewrite Triggers
When should you rewrite instead of harden?
Rewrite If:
- Security flaw is fundamental - e.g., storing passwords in plain text
- Architecture is wrong - e.g., polling when you need WebSockets
- Technical debt exceeds value - hardening would take longer than rewriting
- Performance is structurally bad - e.g., O(n²) when O(n) is possible
- You don't understand it - if you can't explain it, you can't maintain it
The Sunk Cost Trap
"But I spent 3 hours on this!"
Doesn't matter. The question is: Will hardening this take more or less time than rewriting?
Rule of thumb: If hardening a component would take more than 2x the time to rewrite it properly, rewrite.
Technical Debt Assessment
Every prototype accumulates technical debt. Categorize it:
| Debt Type | Example | Urgency |
|---|---|---|
| Deliberate Debt | "We'll add caching later" | Scheduled |
| Accidental Debt | Discovered edge case bug | Before ship |
| Bit Rot | Deprecated dependency | Soon |
| Reckless Debt | "We'll figure it out" | Now (or never) |
Reckless debt is the killer. If you shipped code without understanding it, you're going to pay interest forever.
Failure Patterns
1. The Perfectionist Trap
Symptom: Nothing ever ships because nothing is "production ready."
Fix: Define "good enough" before you start hardening. Hit that bar and ship.
2. The Ship-and-Pray
Symptom: Everything ships as prototype. Production is constant firefighting.
Fix: Use the risk matrix. At minimum, harden high-risk components.
3. The Rewrite Addiction
Symptom: "This would be better if we just started over" - said repeatedly.
Fix: Rewrites must be justified. If you can't quantify why hardening won't work, don't rewrite.
Quick Reference
The 5-Minute Assessment:
- List all components/modules
- Rate each: High/Medium/Low risk
- Rate each: High/Medium/Low quality
- Apply matrix: Keep/Harden/Rewrite
- Estimate time for Harden/Rewrite items
Hardening Priorities:
- Security (auth, input validation)
- Data integrity (storage, processing)
- Error handling (user-facing errors)
- Logging (production debugging)
- Tests (preventing regressions)
Rewrite Threshold: If hardening takes >2x rewrite time, rewrite.