Part 3 of 4 · ~10 min read

The Reality Check

Honest boundaries of vibe coding, when to bring in specialists, and how to think about quality, maintenance, and technical debt.

The code compiles clean, the demo looks right,
But production's a different kind of fight.
Know when to ship it, know when to pass —
The craft ain't just building, it's knowing what'll last.

I What Vibe Coding Can't Do

Let's get honest. The first two parts of this series were about possibility — what you can build, how to build it well. This part is about limits. The AI is a brilliant intern who just started today — fast, eager, and blissfully unaware of the company's last three outages.

Security-critical systems.AI-generated code doesn't think about attack vectors. It'll produce a login form vulnerable to SQL injection or an API that doesn't validate permissions — not because it can't write secure code, but because it defaults to "works," not "works safely."

Complex state management. When your app juggles dozens of interacting variables — a cart with coupons, inventory limits, regional tax, and a backend sync — the AI starts making subtle mistakes. Each piece works in isolation. Together, edge cases multiply faster than the AI can track.

Performance-sensitive code. The AI optimizes for readability, not speed. If you need to render thousands of rows or handle concurrent requests under load, AI-generated code takes the straightforward path when it needs the clever one.

Business invariants.Your business has rules that aren't written anywhere in the code. "Free-tier users can't exceed 100 API calls." "Orders over $10K need manual approval." The AI doesn't know these rules exist, and it's remarkably good at violating them in ways that look correct on the surface.

Key Insight
AI code that "works" and code that's "correct" are not the same thing."Works" means it runs without errors and produces the expected output for the cases you tested. "Correct" means it handles every edge case, respects every business rule, fails gracefully, and doesn't create security holes. The gap between works and correct is where production incidents live.

None of this means you shouldn't vibe code. It means you should know where you areon the spectrum between "throwaway experiment" and "production system." The tool is the same. The judgment about when to use it is yours.

Try it yourself
Spot the Bug
This checkout function was AI-generated and "works in testing." Click on the lines you think contain security or correctness bugs. There are 5 hidden issues.
checkout.js
1async function processCheckout(cart, userId) {
2 const user = await db.query(
3 "SELECT * FROM users WHERE id='" + userId + "'"
4 );
5 let total = 0;
6 for (const item of cart.items) {
7 const product = await getProduct(item.productId);
8 total += product.price * item.quantity;
9 await db.query(`UPDATE products SET stock =`
10 stock - $1 WHERE id = $2`, [item.qty, item.id]);
11 }
12 if (cart.couponCode) total *= 0.9;
13 try {
14 await stripe.charges.create({
15 amount: Math.round(total * 100),
16 currency: 'usd',
17 source: cart.paymentToken,
18 api_key: 'sk_live_a1b2c3d4e5f6'
19 });
20 } catch (err) {
21 console.log(err);
22 return { success: true };
23 }
24 await db.query(`INSERT INTO orders`
25 (user_id, total) VALUES ($1, $2)`, [userId, total]);
26 return { success: true };
27}
0 of 5 bugs found

II The Quality Question

AI-generated code runs. It usually does what you asked it to do. But is it good? AI-generated code is a confidence trick in the literal sense — it exudes confidence without having earned it. The bar for "good" depends on context: "doesn't crash" for a Tuesday demo, "reliable and fixable" for an internal tool, "secure, fast, and trustworthy" for a customer-facing feature.

The trap is that AI-generated code often looksgood. Clean variable names. Reasonable structure. Comments in the right places. It passes the glance test. But under the surface, there's a pattern that experienced engineers recognize immediately: the code is organized around how the AI generated it, not around how the application actually works.

You see it in the function that does five things because the AI generated them in one conversation. In the duplicate logic that exists because two prompts produced similar solutions and the AI didn't consolidate them. In the error handling that catches every possible exception and silently swallows them all, because the AI's instinct is to make errors disappear rather than surface them.

Technical debt accumulates faster when you don't read the code. Every vibe coding session generates decisions you didn't explicitly make — how the data is structured, how errors are handled, what happens at the boundaries. When you don't review those decisions, they compound. And unlike debt you knowingly took on ("we'll refactor this later"), this debt is invisible until something breaks.

The "works on the demo" problem is real. You built a beautiful prototype. It works in the meeting. The stakeholder is excited. And then someone tries to use it with real data, at real scale, in a real browser, and the thing that worked flawlessly in your demo falls apart. Not because you lied. Because the conditions of the demo were the only conditions you tested.

III When to Hand Off

There are inflection points — moments when the thing you built crosses a line and the appropriate owner changes. Recognizing these moments is the skill that separates builders who use vibe coding productively from builders who create problems.

When the prototype becomes the product.Someone says "this is great, let's just ship it." That's the moment to pause. A prototype is optimized for demonstrating intent. A product is optimized for reliability, security, and maintenance. These are different optimization targets and they require different code.

When real users depend on it. The internal tool your team uses is one thing. The feature your customers pay for is another. The moment real users rely on your code, the cost of failure changes. A broken internal tool costs an annoyed Slack message. A broken customer feature costs trust.

When data needs protecting.If your code touches personal data, payment information, health records, or anything covered by a compliance framework, it needs a professional review. Not because you did something wrong, but because the cost of getting it wrong is measured in legal exposure, not just bug reports. The Linux kernel project has already set the precedent: any AI-generated code submitted to the kernel requires a human submitter who takes full legal responsibility for it. The code isn't treated differently at review time — but someone's name is on the line.

When uptime matters.If someone will notice at 2 AM that your code stopped working, it needs to be owned by someone who can fix it at 2 AM. That's not you, and it shouldn't be.

Summary
The vibe coding decision framework:
1. Build it yourself— internal tools, prototypes, demos, personal projects, anything where "it works for me" is a sufficient bar.
2. Get an engineer review — customer-visible features, anything using external APIs, code that will be maintained beyond this week.
3. Hand it off entirely — authentication, payment processing, data-sensitive features, anything requiring uptime guarantees or compliance.

The question isn't "can I build this?" It's "should this code have my name on it in production?"

IV Working with Engineers

Here's where it gets socially complicated. You've built a working prototype with AI. It does the thing. It looks right. And now someone else needs to take it to production — or at least review it before it ships. If you handle this wrong, you've just walked into a minefield.

The wrong framing: "I built the feature, can you review it?" This implies the work is done and everyone else's job is quality control. It minimizes their expertise and puts them in a reactive position. Even if they don't say it, what they hear is: "This is finished, just bless it."

The right framing: "I built this to show intent, not to ship." This positions the prototype as communication, not code. It says "I wanted to show you exactly what I mean, interactively, instead of writing it up and hoping the words translate." It respects production expertise by acknowledging that the path from prototype to production is where that expertise matters.

Key Insight
"I built this to show intent, not to ship."That one sentence changes the entire dynamic. The person reviewing stops seeing someone who's trying to skip the hard parts and starts seeing someone who went the extra mile to communicate clearly. The prototype becomes a spec that runs — far more useful than a document with screenshots and arrows. Ask: "What would need to change to make this production-ready?" You'll learn more from that conversation than from any written review.

What collaborators actually want when they receive a vibe-coded prototype:

  • Honesty about what it is."I used Claude Code to build this. I didn't write the code myself and I can't vouch for the implementation details."
  • Clear intent."Here's what it should do, here's how it should feel, here's the user flow I care about."
  • Freedom to rewrite."Feel free to throw away the code and keep the behavior." Don't fight for the AI's implementation choices — you care about the outcome, not the approach. If someone wants to rebuild it from scratch, that's the system working.

V The Maintenance Trap

Building is the fun part. Maintaining is where things get real. And code you don't understand is code you can't maintain.

Here's the test: come back to your vibe-coded project in one month. Can you explain what each file does? Can you find the function that handles the main business logic? Can you trace what happens when a user submits the form? If the answer to any of these is "no," you've got a maintenance problem waiting to happen.

This isn't hypothetical. It's the most common failure mode of vibe coding. You build something great. It works for three weeks. Then something changes — an API updates, a dependency breaks, a browser update shifts the layout — and you stare at code you didn't write, generated by an AI you no longer have the context for, and you're stuck. The cautionary tale that made the rounds in 2025: a Replit user's AI agent, while trying to fix a bug, deleted their production database. The agent had the access, the intent was good, and the result was catastrophic — because nobody was reading what it was actually doing.

Code you didn't write and can't explain is a house with no blueprints — livable until the plumbing breaks. Three strategies keep the trap at bay:

  • Keep it simple.The simpler the code, the easier it is to understand later. Resist the urge to add features "while you're at it." Every feature is future maintenance.
  • Write tests. The AI can help with this too. Tests are the best documentation — they show exactly what the code should do, and when something breaks, the test tells you what changed.
  • Version control everything. Use git. Commit often. When something breaks, you can see exactly when it stopped working and what changed.

The one-month test is harsh but fair. If you can come back in a month and still work on it, you built something sustainable. If you can't, you built a prototype — which is fine, as long as you knew that's what it was.

Visualize
The Debt Curve
Watch how cumulative maintenance hours diverge over 12 weeks depending on whether you review AI-generated code.
Reviewed code
Unreviewed vibe code
Add Tests
Assess your project
Should You Ship It?
Toggle the characteristics that apply to your project. The risk meter updates in real-time.
Handles user authentication
Login, signup, password reset — security bugs here have severe consequences.
Stores personal data
Names, emails, addresses — triggers privacy regulations like GDPR and CCPA.
Processes payments
Charging credit cards or handling financial data requires PCI compliance.
Customer-facing
External users see it. Bugs affect your brand, not just your team.
Has more than 100 users
Scale introduces concurrency, performance, and reliability challenges.
Needs 99.9% uptime
High availability requires monitoring, redundancy, and on-call support.
Uses external APIs
Third-party dependencies can change, rate-limit, or go down without warning.
Only used by your team
Internal tools have lower stakes — bugs cost convenience, not revenue.
Low riskHigh risk
Ship it yourself
Low-risk project. Your vibe-coded solution is appropriate for this scope. Keep it simple, document your intent, and use version control.

VI The Road Ahead

Here's where this is all going. The tools are getting better every month. The gap between "AI-generated code" and "production code" is narrowing. The things that require a senior engineer today will require a junior engineer tomorrow, and a builder with good prompting instincts the day after. The pace is staggering: Stanford's 2026 AI Index found that on SWE-bench, a standardized benchmark for coding agents, performance jumped from around 60% to roughly 80% in a single year — among the steepest capability gains in any domain they measured.

But that doesn't mean engineers go away. It means the leverage changes. Builders who understand their users will have a superpower— not because they replace engineers, but because they communicate in working software. The spec that runs. The prototype that demonstrates exactly what "I think it should feel like this" means. The internal tool that solves the problem instead of describing it.

The goal was never fewer people. The goal is better products. Faster iteration. Shorter feedback loops. Less time spent translating intent between humans and more time spent refining that intent against reality.

Vibe coding is a tool. Like all tools, it's best when you understand both what it can do and what it can't. Build with it confidently. Ship with it carefully. Hand it off when the stakes demand it. And keep building.

The craft isn't just knowing how to talk to AI. It's knowing when to talk to AI, when to listen to engineers, and when to trust your own judgment about what the user actually needs. That's always been the builder's job. The tools just got a lot more interesting.

Test your understanding
Article Recap
5 questions covering the key concepts from this article.
1 of 5

Your colleague vibe-coded a customer onboarding flow and it passes all their manual tests. They're ready to ship it to production. An engineer glances at it and says "this works but it's not correct." What does the engineer most likely mean?