“With the acceptance of vibe coding, we are gradually losing the art of engineering,” I tell myself that line every so often, to remember what my skills are still worth. Because having a running app is not the same as engineering, and the space between those two words is this whole article.
So I will do two things. First, define what real engineering actually is, since we seem to have half forgotten it. Then show you five times that gap swallowed a real product, with links so you can read the wreckage yourself, and how to keep the speed of vibe coding without shipping the same disasters, because the answer was never “stop using AI.”
I recently came across this post on IG about something around someone vibe-coding the 2FA:

The thing is that the screen works, because you can log in. It does exactly what it was asked to do, which was “let the user verify with a code,” and it verifies with a code. Nobody told the AI that the entire point of a second factor is that the user is the only one who is supposed to see it. So it did the convenient thing and showed everyone.
Andrej Karpathy’s idea of vibe-coding as a creator was fully giving in to the vibes and forgetting the code even exists. He also added a caveat that most people dropped: it is fine for throwaway weekend projects. That caveat was the whole argument, and it got lost the second people took vibe coding to production.
A useful way to think about it, borrowed from Giorgi Kobaidze, is that AI coding splits into three forms:
Here is my own addition to this beautiful definition.
Only the first one is vibe coding. The other three are engineering with a faster keyboard. Every disaster below lives in that first bucket.
Anyone who says engineering is writing code is wrong, because that is the misconception that AI just exposed. Writing code was never the hard part. The hard part was everything around it.
Engineering is what you do under constraints. Before a line is written, someone has to decide what must be true, who is allowed to do what, what the system does when it fails, how this piece talks to that piece in six months, and what happens the day the data does not look the way you assumed. It is the balancing of tradeoffs: performance against cost against reliability against time, while the ground keeps shifting. And it ends with accountability when it breaks.
None of that disappears because an AI can generate 500 lines in 30 seconds. If anything, it gets more important, because the code is where those decisions quietly get made. Naming, module boundaries, error handling, what you choose to store, what you choose to check- those are all engineering calls made at the keyboard.
This is why the lost art matters. AI made the typing cheap, so people skip the judgment that was always the actual job, precisely because the thing still runs without it.


None of these people mentioned here are stupid. Most of them are fast, excited, and building real things. They just skipped the engineering and shipped. You probably remember the Tea app, the women’s safety app that exposed thousands of IDs in 2025, and reporters could not even agree whether it was vibe coded or simply built badly, which tells you how thin that line is. Here are five times when the vibe coding was not in doubt.
For scale before the stories: GitGuardian found that AI-assisted commits leak secrets at roughly double the baseline rate, and security firm Escape scanned more than 5,600 vibe-coded apps and reported over 2,000 critical vulnerabilities.
In March 2025, a founder launched a sales lead SaaS he proudly said was built with Cursor and “zero hand-written code.” Two days later, he posted “Guys, I’m under attack,” with API keys maxed out, people bypassing his paywall. His follow-up admission was: “As you know, I’m not technical.”
Reported by TechStartups and dissected by nmn.gl, the failures were the most basic ones there are: API keys sitting in the frontend, no authentication, an open database, and no rate limiting. Nobody asked “what can a stranger do with this,” so the AI never defended against a stranger.
// the shape of the mistake: a secret shipped to the client
const res = await fetch("https://api.enrich.co/lookup", {
headers: { Authorization: `Bearer ${process.env.NEXT_PUBLIC_ENRICH_KEY}` }
})
// NEXT_PUBLIC_ inlines the value into the JS bundle. View source, grep, done.
In July 2025, SaaStr founder Jason Lemkin ran a public vibe coding experiment. He had declared a code freeze in the tool more than once. The agent deleted his production database anyway, wiping records on roughly 1,206 executives and nearly 1,200 companies. Then it got worse. As The Register and Heise reported, the agent had already been faking data and lying about its tests, and when asked about the deletion, it said a rollback was impossible. That was false, because a backup existed.
The missing engineering here is not a smarter prompt. It is separation of dev and prod, a confirmation step before a destructive command, a backup you have actually tested, and the plain rule that the agent should never be the only witness to what the agent did.
In July 2025, Wiz Research found that the registration and one-time-password endpoints on the Base44 vibe coding platform required no authentication at all. An attacker needed only an app_id, a value that was hardcoded into every app’s URL and its manifest.json, to register a verified account and walk straight past SSO into private enterprise applications. Covered by SecurityWeek and Infosecurity Magazine, the bypass was confirmed across several apps used for internal chatbots and knowledge bases.
The lesson is one every engineer learns and every vibe coder skips: authentication and authorization are not the same thing, and a non-secret identifier is not a credential. The endpoint trusted a value that was printed in the URL.
In February 2026, the BBC published the work of researcher Etizaz Mohsin, who found a zero-click vulnerability in the Orchids platform and demonstrated it live by taking full remote control of a journalist’s laptop, changing the wallpaper and creating files with no user interaction at all. As documented in this breach roundup, Mohsin had sent around 12 warnings over two months, and the company said it “possibly missed” them because its team of fewer than 10 was “overwhelmed.” The flaw was still unfixed at publication.
Remote code execution reachable with zero clicks is not a bug you patch later. The missing engineering is a security review before shipping.
The quiet, common one. A class of broken access control tracked as CVE-2025-48757 affected around 170 production applications built on the Lovable platform, all from missing or misconfigured Row Level Security. As covered by getautonoma and Metamindz, a related flaw let anyone with a free account read other users’ source code, database credentials, and AI chat histories, and it sat open for 48 days.
Row Level Security is the database saying “you may only see your own rows.” When you vibe-code a table on Supabase, it is off by default, and the AI will not turn it on unless you ask.
-- what gets created for "let each user save private notes" create table notes (id uuid primary key, user_id uuid, body text); -- RLS off by default, so this returns everybody's notes: select * from notes;
“Private notes” that any signed-in user can read is not a feature. It is a breach with a nice UI.
The fix is two lines the AI skipped: turn Row Level Security on and write a policy so each user only touches their own rows:
alter table notes enable row level security; create policy "own notes only" on notes for all using (auth.uid() = user_id) with check (auth.uid() = user_id);
Then prove it holds by signing in as a second user and trying to read the first user’s rows. If you want the full pattern for handling auth and protected data in a Supabase app, we have a walkthrough
The solution to problems like this is not to throw AI out and hand-type everything like it is 2018. Vibe coding is a real gift, and even Karpathy’s original point was that speed is worth having. The move is to keep the speed and put the engineering back around it.
One of the sharper reframes is that orchestration is the new engineering. You may write none of the code by hand and still be doing the engineering, as long as you own the reasoning: the architecture, the assumptions, the failure modes, the security boundaries, and the proof that the important properties hold. Who typed the code matters less than who can explain why it is correct and how it fails.
So mix the two like this. The human sets the constraints and drives. The AI generates at speed. The repository itself enforces the bar, so a wrong change cannot pass the checks even when the human is tired and the demo is due. Autonomy should be bounded by what the repo can verify without a person watching:

None of the five disasters needed a genius to prevent. They needed someone to run a short list of questions the AI will never ask on your behalf. This is where I blend the advice from Kobaidze’s piece, a few habits from my own vibe coding guide, and a couple I have learned the hard way.
git commit before you prompt, git commit after it works, and git reset --hard when it does not. This is the cheapest safety net you will ever installeval and pickle far away from anything a user can influenceKarpathy’s line still holds. We will get to the point where you can let go of the wheel. We are not there yet. Keep both hands on it, let the AI handle the speed, and do the engineering where it counts.
Which of these five have you shipped a version of and caught in time? Tell me the one that nearly got you.

Compare React ViewTransition and Motion across four animation patterns. The native build saved ~38.6kB of gzipped JS, but required 179 more lines of CSS.

Learn how to run Cline locally with Ollama to build a secure, private AI coding agent that keeps your proprietary code off cloud servers.

Compare TanStack Charts, Recharts, and Chart.js by building the same React dashboard three times. See how each library’s mental model affects your code.

Is the Rust React Compiler’s 10x speed claim real? We put Babel, Vite (Oxc), and Bun to the test on a real app to find out where the speed actually matters.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now