The demo works. Production is a different job.
You described an app to Lovable, Cursor or Bolt, and a few hours later you had something that runs. Pages, a login, a database, a working flow. It demos beautifully. So you point real users at it, and that is where the trouble starts.
The reason is boring and consistent: AI writes code that works before it writes code that is safe. Security, error handling and access control are invisible in a demo, so the model skips them by default. The tools are behaving exactly as designed; a demo simply never exercises the code that protects real users. In Veracode’s 2025 analysis of AI-generated code, 45% of it introduced at least one vulnerability from the OWASP Top 10, and independent studies put the vulnerability density at roughly 2.7 times that of human-written code.
We wrote about why vibe-coded projects stall in the last 20% of a vibe-coded project. This is the other half: what you actually do about it, in the order that matters.
Start by finding out what the AI actually built
You cannot harden code you do not understand. Before you change a line, get an honest inventory of what is under the hood, because vibe coding hides these decisions from you while you build.
The stack
Which framework, which database, which hosting. The AI chose these for you. You need to know what they are before you can judge whether they will hold.
Where the secrets live
Find every API key, database URL and token, and check whether it sits in the frontend where any visitor can read it. This is the single most common vibe-coding leak.
The data model
What tables exist, what links to what, and crucially: what stops one user from reading another user's rows. Often the answer is nothing.
The auth model
Who can do what, and whether that is checked on the server or only hidden in the interface. A hidden button is not a permission.
An afternoon of reading before you touch anything saves you from fixing the same problem three times.
The security holes come first, and in this order
Not every gap is equally dangerous. Fix the things that get you breached today before the things that make you slower next month. This is the order we work in.
Get secrets out of the frontend
API keys and database credentials in client-side JavaScript are readable by anyone who opens dev tools. Move every secret to server-side environment variables and rotate the ones that were exposed.
Lock down the database
Turn on row-level security on every table so the database itself enforces who sees what. The classic Lovable-plus-Supabase leak is a table anyone can read: user A quietly pulling user B's data.
Check permissions on the server
Every API call that changes or returns data has to verify, server-side, that this user is allowed to do this to this record. Never trust the frontend to enforce it.
Close injection and XSS
Parameterized queries instead of glued-together SQL strings, and escaped output instead of raw user input rendered into the page. These are the oldest attacks in the book and AI reintroduces them constantly.
Add rate limiting
Nothing stops someone hammering your login or your paid API a thousand times a second, because the AI never adds it. A simple limit per IP turns an expensive outage into a non-event.
A demo has one friendly user doing exactly what you expected. Production has strangers, bots and mistakes hitting every path at once. Security is the code that handles the second case, which is precisely the code a demo never needed.
Then make it survive contact with real users
Once it is safe, make it sturdy. The happy path always works. Production is everything that happens when the input is wrong, the network drops or a service is down.
Handle the unhappy paths
Every external call can time out and every form field can arrive empty or malformed. Wrap them, validate inputs on the server, and return a real message instead of a white screen or a crash.
See what is happening
Structured logging, uptime monitoring and an error tracker like Sentry. Without them you learn about outages from an angry customer instead of an alert, hours too late.
Back up the data
Automated database backups, and a restore you have actually tested once. A backup you have never restored is a guess, not a safety net.
Add a safety net before you change anything
Vibe-coded projects almost never have tests, which means every later edit, by you or by the next AI prompt, is a gamble that nothing else broke. Before you build further, write tests around the paths you cannot afford to break: login, payments, anything that writes data. That is what lets you keep moving fast without breaking production every time.
Deploy like it is real
The gap between a preview URL and a product is a handful of unglamorous steps that vibe coding skips entirely.
Separate environments
A staging environment where you test changes before they hit the users, with its own database. Not one live app you edit in production and hope.
Config and secrets per environment
Keys and settings injected at deploy time, never committed to the repository. Different values for staging and live, managed in one place.
A repeatable deploy
One command or one pipeline that builds and ships, so releasing is not a manual ritual you get wrong at 11pm. HTTPS on, backups scheduled, restore tested.
Know when to stop patching and bring in help
Some of this you can do yourself with the same AI tools that built the app, as long as you know what to ask for. But there is a point where patching stops helping: when the authentication does not fit the architecture, when the database structure will not scale, when a payment integration means unpicking how the whole backend was set up. Those are design decisions, and no amount of prompting fixes a design decision cleanly.
That is the moment a review pays for itself. A vibe coding audit tells you exactly which of the steps above your app is missing and how deep the fixes go, before you spend a month on the wrong one. And if you would rather hand the hardening and the hosting to a team that does this daily, that is managed development: you keep tweaking in Cursor while we keep the production side standing.
Conclusion: you are hardening, not rebuilding
The mistake teams make is treating a vibe-coded MVP as either finished or worthless. It is neither. It proved the idea faster than any traditional process could have, and that is genuinely valuable. Production readiness is the second half of the job, and it is a different half.
The MVP proved the idea
Vibe coding is brilliant for that. Fast, cheap, good enough to show real users and learn whether the thing is worth building at all.
Production is a different discipline
Security, reliability, tests and deploy. Work the checklist in order and you harden what you have instead of starting over.
Work down the list from the top, fix the breach-today items first, and you turn a promising prototype into something you can safely put in front of paying customers, without losing the speed that got you here.
Is a vibe-coded app safe to use in production?
How do I make a Lovable or Cursor app production-ready?
What is the biggest security risk in AI-generated code?
Do I have to rebuild a vibe-coded app to take it to production?
How long does it take to make a vibe-coded MVP production-ready?
Not sure what your app is missing?
We take vibe-coded apps to production for a living. An audit to map exactly what stands between your MVP and real users, and hands-on help to fix it.