Why Most Developers Can't Actually Build Anything
There's a trend going around called "vibe coding." You open an AI editor, describe what you want in plain English, accept whatever the model spits out, and keep iterating until something seems to work. If it runs, you ship it. If it breaks, you prompt again.
This isn't coding. It's blind coding and it's creating a generation of developers who can prompt but can't build.
The Illusion of Competence
AI has made it trivially easy to generate code that looks correct. A React component here. A Docker Compose file there. A Python script that "handles" your data pipeline. The problem isn't that the code is always wrong, it's that the person prompting has no mental model for what's actually happening underneath.
Here's what I mean:
- They don't know how data structures work. Ask them why their AI-generated list traversal is O(n²) instead of O(n), and they'll stare at you. The code "works" on 100 rows but times out on 100,000.
-
They don't know how Docker works. They copy-paste a
Dockerfilefrom ChatGPT, build an image, and celebrate whendocker rundoesn't immediately crash. But they can't explain layers, caching, multi-stage builds, or why their image is 2GB for a simple Node app. - They don't understand integration. Their frontend "talks to" their backend, but they don't know how HTTP works, what CORS actually means, or why their WebSocket drops connections under load. Everything is a black box connected to another black box by vibes.
The result? Fragile systems held together by hope and hallucinated confidence.
What Vibe Coding Actually Looks Like
The Junior Engineer Prompt
"Build me a full-stack app with React and Node.js that lets users upload files and stores them. Make it secure and fast."
This is what gets fed into Cursor, v0, or ChatGPT. The output is usually:
- A frontend with
axios.post('/upload') - A backend with
multerdumping files to disk - No auth, no validation, no rate limiting
- A Dockerfile that copies everything and runs
npm startas root - "It works on my machine" until it doesn't
The junior engineer doesn't know what's missing because they never learned to ask the right questions. They got a working demo, and that was enough.
What Deliberate Engineering Looks Like
The Senior Engineer Prompt
"I need a file upload service. Constraints:
- Files up to 100MB, images and PDFs only
- Must validate MIME type server-side, not just extension
- Scan with ClamAV before persisting
- Store in S3 with presigned URLs, never stream through our servers
- Rate limit: 10 uploads/hour per user, tracked in Redis
- Return signed CDN URL for immediate display
- Docker: multi-stage build, distroless final image, non-root user, health checks
- Frontend: resumable uploads with progress, cancel support
Start with the threat model and API contract. Then the storage layer. Then the upload handler. Then the UI."
Notice the difference. The senior engineer isn't asking for code they're defining boundaries, constraints, and failure modes first. They know:
- That client-side validation is cosmetic
- That streaming large files through app servers is a bottleneck
- That Docker images should be minimal and hardened
- That UX requires handling network interruption
The AI still writes the code. But the senior engineer directs it, because they understand the system.
The Real Problem
AI isn't making engineers obsolete. It's making it harder to distinguish between engineers who think and operators who prompt.
The danger of vibe coding isn't that you use AI. Everyone should use AI. The danger is using AI instead of understanding:
| Vibe Coding | Deliberate Engineering |
|---|---|
| "Make me a login system" | "Design auth with refresh tokens, CSRF protection, and OWASP Top 10 coverage" |
| "Dockerize this" | "Optimize layer caching, use non-root, handle graceful shutdown" |
| "Fix this bug" | "Trace the execution flow, identify the race condition, write a regression test" |
| "Make it faster" | "Profile the hot path, reduce N+1 queries, add connection pooling" |
Vibe coding produces demos. Deliberate engineering produces systems.
What to Do Instead
If you're early in your career, here's how to avoid the trap:
1. Learn one layer deeper
Don't stop at "it works." Understand why it works. Read the source code of the libraries you use. Trace a network request from browser to server to database and back.
2. Build without AI sometimes
Write a CRUD app from scratch with no Copilot. Configure nginx manually. Set up a database replica. The friction teaches you what the abstractions hide.
3. Ask "what could go wrong?"
For every feature you build, list three ways it could fail. Then design for those failures. This is the difference between a toy and production code.
4. Study systems, not syntax
Data structures, networking, concurrency, distributed systems, these are timeless. Frameworks change. Fundamentals don't.
5. Use AI as a multiplier, not a crutch
The best engineers I know use AI constantly. But they use it to accelerate decisions they've already reasoned through, not to replace reasoning itself.
The Bottom Line
Vibe coding is seductive because it delivers instant gratification. You get a working prototype in minutes. But software engineering isn't about prototypes, it's about building things that survive contact with reality: scale, security, edge cases, and time.
AI is the most powerful tool we've ever had. But tools don't replace judgment. They amplify it.
If your judgment is blind, so is your code.
Top comments (0)