Learn
What vibe coding is, and where it stops working
Vibe coding means describing the software you want and judging the result by whether it works, not by reading the code. Here is why that goes so well at the start, and the points where it stops being enough.
Short answer
Vibe coding means describing the software you want in plain language, letting a model write it, and judging the result by whether it does what you asked rather than by reading every line. It works well for a first version, because most first versions are shaped like software the model has seen many times. It gets unreliable where code meets state: stored data, permissions, money, and anything that can run twice.
Where the term came from
The phrase comes from a short post by Andrej Karpathy in early 2025: you talk to a model, accept what it writes, and barely look at the code. He meant it for weekend projects, and the name stuck because plenty of people were already working that way.
In practice it is a loop. You describe what you want, the model writes the code, you run it and describe the next thing. You are steering by behaviour instead of by implementation, which is a reasonable way to work on a lot of problems.
Why the first version comes out so well
Models are good at the common shape of things. A sign-up form, a list with filters, an API over a handful of tables: these have been written an enormous number of times, and the model knows what they look like. Most first versions are exactly these shapes.
You also get an honest signal for free. The button either saves the record or throws an error, so you can correct course without understanding the code at all. And the part most people find dullest, the boilerplate around the idea, is the part the model is best at.
Where it stops working
The trouble starts where behaviour stops being visible from outside. In all four places, code is touching state.
Data that has to survive A bug on a screen is visible and fixable. A bug that writes a wrong value into the database leaves a mark that is still there after you fix it. Migrations are the worst case: dropping a column is instant and final.
Who is allowed to do what An app may hide a button while still returning another user’s record from its API. Testing only through the interface with your own account can miss that access-control bug.
Money Prices, totals, tax, refunds. Ordinary arithmetic, which is why it gets skimmed, and a total wrong by one rounding rule looks plausible on screen.
Anything that can run twice Network calls get retried. People double-click. Queues redeliver. Code that is correct once is not automatically correct twice, and nothing you told the model said which actions are safe to repeat.
The failure is rarely that the code does not run
The thing people brace for is code that breaks. That is the easy failure: it announces itself, you paste the error back, you move on. The expensive failure is the opposite. The code runs, reports success, does the wrong thing, and nobody notices for a week.
A concrete version: you add a field to a form. It renders, people fill it in, and the handler that writes the row never learned about it. Every submission succeeds. You find out when someone asks why the notes column has been empty since Tuesday, and no copy exists of what they typed.
Another: a job that charges a customer has no guard against running twice. The payment provider times out, the call is retried, and the retry succeeds. So did the first attempt. Nothing errored, nothing warned, and you hear about it from the customer.
Both are ordinary bugs that experienced engineers write too. What changes here is that nobody read the code, so nobody paused to ask what happens if it runs twice. The loop shows you what you test, and you do not test what never occurred to you.
What changes when other people use it
While you are the only user and the data is test data, none of this costs much. You know what the app should do, you notice when it looks off, and you can throw the database away and start again. Real records, credentials or payment details change that, even in an app only you use.
Other people change it too. They do things you never thought to try. They cannot tell a bug from a deliberate design, so they work around it quietly. And the data they put in is not yours to lose.
That is the moment to get it off your laptop and onto somewhere real, with a database that is genuinely backed up. AppHaven is one option: it deploys on a git push and runs managed PostgreSQL with backups and point-in-time recovery, and the safety review for generated software covers what to check before real records go in.
It also changes what you read: not all of the code, but the parts touching those four things. Ask the model to explain in plain words what the save handler writes.
When vibe coding is the right call
Often it is. A prototype you intend to throw away, an experiment on test data, a one-off script using disposable test data: build those this way and skip the code with a clear conscience. Work differently the moment the app holds records someone would miss, decides who sees what, touches money, or could do damage by running twice. Then read and test those parts before real data goes in.
Common questions
Is vibe coding the same as using an AI coding assistant?
Not quite. Vibe coding in its original sense means not reading the generated code and judging it by behaviour instead. Using an assistant while still reviewing the diff is ordinary programming with a faster first draft.
Can I vibe code something real, or only prototypes?
You can get a real application started this way. What has to change for real use is the checking rather than the writing: data that must survive, permissions, money and actions that can run twice deserve to be read, or explained back to you, before other people depend on them.
Run it on AppHaven.
Run your business app with a managed database, private access and production backups.