Vibe-Coded Prototypes: How to Harden Them
Your AI-generated MVP works, but is it production-ready? Here's how to close the gap.
The Scenario
You used AI to ship a prototype fast. It works. Users are signing up. But now you’re worried:
- Is it secure?
- Will it scale?
- Can I maintain it?
You’re right to worry. Prototypes optimized for speed rarely ship production-ready code.
The Gap
Here’s what AI-generated code typically lacks:
1. Error Handling
What AI does:
const user = await db.users.findUnique({ where: { id } });
return user.email;
What production needs:
const user = await db.users.findUnique({ where: { id } });
if (!user) {
throw new NotFoundError("User not found");
}
return user.email;
Fix: Add null checks, try/catch blocks, and graceful degradation.
2. Input Validation
What AI does:
app.post("/api/users", async (req, res) => {
const user = await createUser(req.body);
res.json(user);
});
What production needs:
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
});
app.post("/api/users", async (req, res) => {
const data = CreateUserSchema.parse(req.body); // Throws if invalid
const user = await createUser(data);
res.json(user);
});
Fix: Use Zod (or similar) on all external inputs.
3. Authentication
What AI does:
const token = jwt.sign({ userId }, SECRET);
res.cookie("token", token);
What production needs:
const token = jwt.sign({ userId }, SECRET, { expiresIn: "1h" });
res.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "strict",
maxAge: 3600000,
});
Fix: Secure cookies, expiration, and session management.
4. Database Queries
What AI does:
const users = await db.users.findMany(); // Returns ALL users
What production needs:
const users = await db.users.findMany({
take: 50,
skip: page * 50,
select: { id: true, email: true }, // Don't return passwords
});
Fix: Pagination, indexing, and field selection.
The Hardening Process
Step 1: Security Audit (1-2 days)
Run through OWASP Top 10:
- Broken access control
- Cryptographic failures
- Injection
- Insecure design
- Security misconfiguration
- Vulnerable components
- Authentication failures
- Data integrity failures
- Logging failures
- SSRF
Tool: Use tools like npm audit, Snyk, or Semgrep.
Step 2: Type Safety (1 day)
- Enable TypeScript strict mode
- Add Zod schemas for all external inputs
- Remove
anyand@ts-ignore
Step 3: Observability (1 day)
- Replace
console.logwith structured logging - Add error tracking (Sentry, LogRocket, etc.)
- Instrument critical operations
Step 4: Testing (2-3 days)
- Write tests for critical paths (auth, payments, data mutations)
- Add end-to-end tests for user flows
- Set up CI to run tests pre-merge
Step 5: Deployment (1 day)
- Document environment variables
- Set up staging environment
- Create rollback plan
- Write runbook for common incidents
Estimated Effort
For a typical MVP (5-10 API endpoints, 3-5 pages):
- DIY: 1-2 weeks (if you know what you’re doing)
- Agent Xero Custom Build: 3-5 days (we do it for you)
- Agent Xero Session: 60-90 minutes (we give you the checklist + guidance)
When to Hire Help
DIY if:
- You’re a senior engineer with production experience
- You have time to learn
- The risk is low (internal tool, no user data)
Hire if:
- You’re early-stage and need to ship fast
- You’re handling sensitive data (payments, PII, health data)
- You don’t have production experience
Ready to harden your prototype? Request a custom build →