
Jurij Tokarski
Is My Vibe-Coded App Ready for Production?
Built in Lovable over a few weekends, liked by its first customers, with a key in the browser. Not ready yet, but fixable in place: a rebuild is the exception.
I built our app in Lovable over a few weekends. Our first customers use it and like it. A friend who codes says our Supabase key is visible in the browser. Is it ready for more users, or do I rebuild it properly?
Not yet, and no rebuild. The gaps in an AI-built app repeat from app to app, and each one has a fix in place.
The friend found the first gap, or half of it. A Supabase key in the browser is harmless or an open door. It depends on which key it is and what stands behind it.
The customers who like the app are the part worth keeping. What's left is making it safe for the people who haven't signed up yet.
It Works for Friends, Not Strangers
Production-ready means the app keeps working for people the founder has never met, and the founder hears first when it doesn't. My working definition is Production Is Done: released to real users, with monitoring in place.
The first customers are friendly users. They follow the path the founder built, report a bug in a message and forgive a broken page. A stranger takes a path nobody tried, and some strangers go looking for gaps on purpose.
Hearing first comes from the setup, not from the users. Error tracking belongs in the first deploy, as in Monitor Day One. Some bugs never throw an error, and only a dashboard shows them.
The holes a stranger finds first are the same in almost every app the AI wrote end to end.
Three Security Gaps Show Up Everywhere
The gaps are a key in the browser, tables without row-level security, and rules that don't check who's asking.
So is a vibe-coded app secure, and is Lovable safe? Maybe. The AI writes code that works, because working is what it was asked for. Security is what the code refuses to do, and nobody asked for that.
A founder once showed me a SaaS built by prompting alone. Within minutes I found three security holes that would have exposed customer data. Another app had its OpenAI key sitting in the frontend code and no database rules at all.
The first gap is the key the friend saw. Supabase ships every app with a public key: the publishable key, or the anon key on older projects.
That one belongs in the browser. The secret key (the service role key on older projects), an AI provider's key or a payment secret never do. The browser's developer tools show which one it is.
The second gap decides whether the public key is safe. The browser talks to the database directly, and row-level security is the only thing between that key and every row. A table with it switched off answers anyone who holds the key.
The third gap hides inside the second. A policy like using (true) keeps row-level security on and lets everyone through anyway. A sound policy checks who is asking: deny by default, then open what each user needs.
The quickest test takes two accounts. Sign in as one and ask for the other's records. If they come back, the rules are open.
Closing the gaps means changing code, and that's where many AI-built apps get stuck.
Why Each Fix Breaks Something Else
Nothing tells the AI what depends on the line it changes. Tests and small changes do.
The founder asks for one fix. The AI reads part of the code and fixes the bug in front of it. It also rewrites a little more than it was asked to, nothing checks the rest, and something else breaks.
The AI writes the visible part fluently: the screens, the forms, the path where everything goes right. The part underneath keeps a product alive: the data rules, the edge cases, what depends on what.
Human developers break things too. Three habits keep the damage small:
- Small changes: one fix per change, so a break points to the change that caused it.
- Checks on every change: types, a build and a few tests catch the break before a user does. Quality Gates puts TypeScript ahead of most unit tests.
- A way back: a feature flag turns a broken change off without a new deploy.
With those habits, the fix-and-break loop stops, and the rebuild question gets a short answer.
Fix in Place, Rebuild by Exception
Each gap has a known fix, so fix it, almost always. A rebuild is for a data model that can't carry what customers ask for next.
A cleanup keeps what already works: the screens customers know, the data they've entered, the flows tested by hand.
A rebuild trades all of that for cleaner code. The new code is usually fine. The cost is the months when nothing ships while it's written.
Even a large fix stays a fix. Taking that exposed OpenAI key out of the browser meant moving the AI calls to a backend and adding database rules. The estimate was two to three weeks on an app that already ran.
When a rebuild does earn its place, the new version can run beside the live one. One product's V1 and V2 ran side by side for eight months.
Should I Rebuild My App From Scratch? covers the same choice for any codebase. An app built in a hosted builder raises one more worry: does fixing it mean leaving the builder?
Keep the Tool, Own the Code
Keep Lovable or Cursor. Owning the code is the easy part. Lovable pushes it to a GitHub repository in the founder's account, where any developer can open it.
The database matters more. A working Supabase backend can stay as it is, with its account and its bill in the founder's name.
On Lovable Cloud, Lovable's default backend, that account is Lovable's, not the founder's. No setting moves it: getting the database into the founder's own Supabase is a manual migration, so plan it before launch. Who Owns the Code My Developer Writes? has the full list.
Moving to Next.js is a separate decision. It pays off when the app needs its own server, for example to keep AI keys out of the browser.
What lets the tools stay is the foundation under them: quality gates, small reviewable changes and feature flags.
On that V1 and V2 product, the designer polished the interface in Cursor or Claude Code, directly in the code. That worked because the foundation came first. How Should My Team Use AI Coding Tools? goes further.
Without that foundation, the second gap is common, and there's a public count of it.
One Showcase App in Ten Was Open
In March 2025, the security researcher Matt Palmer scanned 1,645 apps from Lovable's own showcase. In 170 of them, about one in ten, anyone could read the data, and in some cases change it. Row-level security was missing or too loose.
He checked only their front pages. The flaw was published as CVE-2025-48757 in May 2025.
Those apps worked for their makers too. More users means more strangers, and the two-account test finds the open door before one of them does.
How I Rescue One in a Week
I use the same AI coding tools every day, so a rescue doesn't take them away. My vibe code rescue is one week. I read the code, the database rules, the keys and the deploys end to end, then move every account into the founder's name.
Then I stop the bleeding: leaked keys rotated, open records closed, the urgent break fixed. The week ends in a plan of what to fix, keep or rebuild, ranked.
Supabase sits outside my default stack, so I judge a Supabase app per project. The plan works for whoever comes next: me by the week, any developer, or nobody. The price is on the homepage.
What the Founder Should Do Now
One week of fixes: rotate the key, switch row-level security on, add error alerts.
The key comes first. If it's the publishable or anon key, it stays, and the work moves to the rules. If it's any other key, the call moves to a server and the key gets rotated, since the old one has already left the founder's hands.
Row-level security goes on next, for every table, with the two-account test against each one. Error alerts go in last, so the next failure reaches the founder before a customer writes in.
After that week, the founder keeps building in Lovable, one small change at a time, with checks on each. The app isn't a rebuild away from production. It's a week of fixes away.
Got thoughts on this? Reply by email.

Jurij Tokarski
I run a solo business and produce software. Usually I'm shipping for clients or building for myself. Sometimes I pause to write about it.