Vibe Coding in Production: What Actually Happens When AI Writes Your Codebase
on Ai, Coding, Engineering, Llm, Productivity, Softwareengineering
Introduction
“Vibe coding” — the term that Andrej Karpathy coined for letting AI write your code while you just… steer the vibe — has gone from meme to mainstream engineering practice in 2026. Startups are shipping full products with two engineers and Claude Code. Solo developers are building SaaS tools they’d have needed a team for three years ago.
But what does it actually look like when AI-generated code hits production? What breaks? What works better than expected? This post is an honest engineering postmortem across a year of AI-assisted development at meaningful scale.
Photo by Chris Ried on Unsplash
The Promise vs. The Reality
The promise: describe what you want, AI writes it, you ship it.
The reality: approximately true, with a list of footnotes that matters a lot in production.
Let’s break down each layer.
What AI Gets Right (Genuinely)
Boilerplate and Structure
AI is extraordinary at generating boilerplate that’s simultaneously tedious to write and risky to get wrong. REST endpoint stubs, database migration scripts, Docker Compose files, CI/CD YAML — these come out clean, consistent, and usually correct on the first pass.
A typical CRUD endpoint that used to take 20 minutes now takes 90 seconds. That’s not hype, it’s a real productivity unlock.
Test Generation
Given a function, AI writes comprehensive test cases faster than most developers do. More importantly, it includes edge cases developers tend to skip (empty strings, null inputs, off-by-one boundaries) because it’s seen thousands of bugs from exactly those cases.
# You write this:
def parse_duration(s: str) -> int:
"""Parse a duration string like '5m30s' into seconds."""
...
# AI generates tests for:
# - "5m30s" → 330
# - "0s" → 0
# - "1h" → 3600
# - "" → ValueError
# - "999999h" → overflow handling
# - "5M30S" → case sensitivity
# - "-5m" → negative input handling
Refactoring
Extracting a method, renaming consistently across a module, converting callback-style code to async/await — AI handles these transformations accurately and quickly. It’s basically a context-aware refactoring tool.
Where It Falls Apart in Production
1. Security
This is the big one. AI models are trained on the entire internet, including the insecure parts. Left unguided, they produce code that:
- Constructs SQL queries with string formatting instead of parameterized queries
- Stores passwords in environment variables (better than hardcoding, but still bad)
- Skips input validation on API endpoints
- Uses
eval()for “convenience” - Generates JWT implementations instead of using vetted libraries
Fix: Add security requirements to your system prompt. Explicitly state: “Always use parameterized queries. Never eval(). Validate all inputs. Use established auth libraries.”
Review AI-generated code with a security lens before merging. This is non-negotiable.
2. Performance at Scale
AI writes code that’s correct for the happy path but often misses performance implications at scale:
# AI writes this (O(n²) without noticing):
def find_duplicates(items: list) -> list:
duplicates = []
for i, item in enumerate(items):
for j, other in enumerate(items):
if i != j and item == other and item not in duplicates:
duplicates.append(item)
return duplicates
# Should be:
def find_duplicates(items: list) -> list:
seen = set()
duplicates = set()
for item in items:
if item in seen:
duplicates.add(item)
seen.add(item)
return list(duplicates)
This kind of issue is invisible in unit tests (which run against small datasets) and only surfaces under production load.
Fix: Ask AI to analyze time and space complexity after generating algorithms. Add performance requirements to prompts: “This function will be called 10,000 times per second.”
3. Context Window Drift
Long sessions of AI-assisted coding accumulate context that starts to work against you. After 50+ turns, the model begins:
- Forgetting constraints established early in the session
- Repeating patterns it “learned” from earlier bad code in the same session
- Contradicting itself between files
Fix: Use compact, stateless prompts for each feature. Treat the context window like a database transaction — bounded and rolled back after use. Don’t rely on an AI remembering what you told it 40 messages ago.
4. Library Version Confusion
AI models have a training cutoff. When they write code using a library that changed significantly since their training data, they generate code against the old API:
# AI writes (LangChain 0.1 pattern — outdated):
from langchain import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run(input)
# Correct in 2026:
from langchain_core.runnables import RunnableSequence
chain = prompt | llm
result = chain.invoke({"input": input})
Fix: Provide relevant library documentation or examples in the prompt. Specify version numbers. Always test imports before trusting generated code.
Patterns That Work Well in Practice
The Spec-First Pattern
Write a detailed spec as a markdown comment at the top of the file before asking AI to implement:
"""
UserService
===========
Manages user accounts with the following behavior:
- create_user(email, password) → creates user, hashes password with bcrypt, sends verification email
- get_user(user_id) → returns User or raises NotFound
- update_email(user_id, new_email) → validates format, checks uniqueness, triggers re-verification
- delete_user(user_id) → soft-delete (sets deleted_at), does not cascade immediately
Constraints:
- Email must be unique (case-insensitive)
- Password minimum 12 characters
- All operations are async
- Use repository pattern — no direct DB calls from service layer
"""
AI with this spec produces far more consistent, well-structured code than AI with a vague natural language request.
The Review Loop Pattern
Never accept the first output. Use a three-pass review:
- Correctness: Does it do what was asked?
- Security: Any obvious vulnerabilities?
- Maintainability: Will the next developer understand this?
Ask AI to review its own code with each lens. It catches ~60% of its own issues this way.
The Incremental Integration Pattern
Don’t ask AI to write entire systems at once. Generate:
- Data model → review + integrate
- Business logic → review + integrate
- API layer → review + integrate
- Tests → review + integrate
Each integration point is a checkpoint where human judgment catches systemic issues before they compound.
Organizational Impact
Photo by Annie Spratt on Unsplash
Team Dynamics
“Senior engineers got more senior, junior engineers got junior-er” is what’s playing out at many companies. Senior engineers with AI tools are wildly more productive. Junior engineers without strong fundamentals struggle to evaluate AI output — they can’t tell good code from plausible-looking bad code.
The skills that matter more now: code review, system design, security intuition, debugging production issues. The skills that matter less: memorizing syntax, writing boilerplate.
Ownership and Accountability
When a bug ships in AI-generated code, who’s responsible? This is a cultural and legal question organizations are still working through. The practical answer: the engineer who merged it. Code review is the quality gate, and that responsibility doesn’t transfer to the AI.
The Current Honest Assessment
Vibe coding works for:
- Prototypes and MVPs (excellent)
- Internal tooling (great)
- Well-defined, isolated features (great)
- Test suites (great)
- Documentation (great)
Vibe coding needs careful management for:
- Security-critical code paths
- High-performance algorithms
- Complex stateful systems
- Anything touching external money/PII
Vibe coding doesn’t replace:
- System architecture decisions
- Production incident response
- Complex distributed systems debugging
- Long-term maintainability planning
Conclusion
AI-assisted coding in 2026 is genuinely transformative, but it’s a power tool, not an autonomous collaborator. The teams winning with it are those who’ve figured out the workflow — the checkpoints, the prompting discipline, the review patterns — rather than just pointing AI at a problem and hoping for the best.
The engineering skills that made great developers great before still matter. What’s changed is the leverage those skills can apply. A great engineer with AI can now do what a small team could previously. That’s real. Just go in with eyes open about where the friction is.
이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)
