WorkBook a call

Guide

A production audit for your vibe-coded app

A vibe-coded app is rarely ready for production as it stands, but you can find out how far off it is yourself in an afternoon. Run the seven checks below, one area at a time, and compare what you find with what good looks like. Most apps need hardening, not a rewrite.

By Max Winter-Leinweber8 min read

Term coined
Andrej Karpathy, early 2025
Areas to audit
Seven
Check first
Data access rules
Usual fix
Harden the code, not rebuild

How to use this audit

Would your app survive one curious user opening the browser's developer tools? That's the question this audit answers. Work through the seven areas in order, because they're ranked by how much damage a failure does, and note each one as fine, needs work or broken.

Vibe coding, the term Andrej Karpathy coined in early 2025, means describing what you want to an AI and accepting the code without reading it. Lovable, Bolt, v0 and Replit made it possible for founders without a coding background to ship a working product in a week. The catch is that the AI tested what you saw in the preview: the happy path, with one user, on a good day. Production is everyone else.

You'll need a second browser or a private window, two test accounts, and access to your hosting, database and Stripe dashboards. You don't need to read the code.

1. Data access

This is the most serious flaw we see in vibe-coded apps, so check it first. Lovable and several other builders have the browser talk straight to Supabase, using a public key that sits in your frontend by design. Row level security (RLS) is then the only thing stopping one user reading every other user's rows.

How to check

  1. Open the Security Advisor in the Supabase dashboard and note every table flagged with RLS disabled.

  2. Read each policy and look for ones that simply return true, which allow everything.

  3. Sign in as test user A, open the network tab, find a request that loads a record, and change the ID to one belonging to test user B.

  4. Repeat while signed out.

What good looks like

RLS is on for every table, each table has policies for read, insert, update and delete written for its purpose, and swapping IDs returns nothing. If you can see user B's data from user A's session, stop the audit and fix this today.

2. Secrets

Any secret key that reaches the browser is public. In a Vite app, every environment variable starting with VITE_ is bundled into the JavaScript. In Next.js it's NEXT_PUBLIC_. A leaked OpenAI or Stripe secret key can run up a large bill overnight.

How to check

Search the repository for sk_, sk-, api_key and secret, and look at every environment variable with a public prefix. Then load the live site, open developer tools, and search the loaded JavaScript files for the same strings.

What good looks like

The only keys in the frontend are ones designed to be public, such as the Supabase anon key and the Stripe publishable key. Everything else lives in server code or an edge function, and any key that was ever exposed has been rotated, not just moved.

3. Auth edge cases

Sign-in almost always works. The paths around it are where vibe-coded apps get shaky, because nobody prompted for them.

How to check

  • Reset a password and use the link twice

  • Leave a session open overnight and try to save something

  • Change the account's email address

  • Delete an account, then sign up again with the same email

  • Sign up with Google, sign out, then try email and password with the same address

  • Open a page that needs a login while signed out

What good looks like

Each case ends in a clear message or a sensible redirect, never a blank screen, a duplicate account or a page that half loads. Deleted accounts take their data with them, which UK GDPR expects anyway.

4. Payments

Taking money is easy. Handling what happens after is where it goes wrong. Stripe can send the same webhook event more than once, so a handler that doesn't check for duplicates can add a month's credit twice or book the same slot twice.

How to check

In Stripe's test mode, run a successful payment, a declined card, a cancellation and a refund. Then resend one webhook event from the Stripe dashboard and see whether anything happens twice. Finally, find where the app decides a user has paid: is it a webhook on the server, or a redirect to a thank you page that anyone could visit?

What good looks like

Webhooks are processed on the server with the signature verified, handled event IDs are recorded so repeats do nothing, failed renewals and cancellations change the user's access, and the success page grants nothing on its own.

5. Deploys and rollbacks

If every prompt goes straight to the live app and the live database, one bad change reaches every user at once. The question is how quickly you can undo it.

How to check

  • Is there a staging environment with its own database, or does everything happen in production?

  • Can you roll the site back to yesterday's version in a couple of clicks? Vercel and Netlify both keep previous deployments for this.

  • Are database changes stored as migration files in the repository, or made by clicking around the dashboard?

  • When did you last restore a database backup, and did it work?

  • Are you making changes in the builder and in the repository at the same time?

What good looks like

Separate development, staging and production databases, schema changes through migrations, one place where changes are made, and a backup you have actually restored at least once. The repository, hosting, domain, database and Stripe account are all in your name.

6. Tests

Most vibe-coded apps have no automated tests at all, which means customers are the test suite. You don't need many. You need the few that cover what makes money.

How to check

Look for a tests or e2e folder and a workflow file under .github in the repository. If there are tests, check whether they run on every push and whether the last run passed. Then notice how often a prompt that fixed one thing broke another in the last month.

What good looks like

End to end tests for sign-up, sign-in, checkout and the core workflow, run automatically on every push, with a failing test blocking the deploy. Playwright is a good default. Error tracking such as Sentry catches what the tests miss, so you hear about failures before customers email.

7. Cost

Generated code is written to work, not to be cheap. The usual surprises are AI calls with no limits, queries that fetch every row, and builder credits spent undoing changes.

How to check

Find every endpoint that calls an AI model and ask what stops one user calling it a thousand times. Check whether spending limits and alerts are set on your AI provider, hosting and database accounts. Load your busiest page with the network tab open and look for requests that return far more rows than the screen shows.

What good looks like

Rate limits on anything that costs money per call, a hard spending cap where the provider offers one and alerts where it doesn't, pagination and database indexes on large tables, and a rough monthly cost per active user you could explain to an investor.

Reading your results

Anything broken in areas 1, 2 or 4 is a launch blocker. Fix those before you take payments or store personal data, because a flaw there can become a data breach you have to report under UK GDPR. Areas 5 to 7 can be improved while the app is live.

If most areas came back as needs work, that's normal, and it still usually means hardening rather than rebuilding. A good developer keeps what works, fixes what the audit found and tidies only the files you change every week. If someone's first suggestion is a full rewrite, ask them why. Scryptic does this work as part of full builds, from £10,000 depending on complexity, and you keep the code and every account throughout.

Frequently asked questions

What is vibe coding?
Vibe coding is building software by describing what you want to an AI in plain English and accepting the code it writes without reading it closely. Andrej Karpathy coined the term in early 2025. Tools like Lovable, Bolt, v0 and Replit have made it popular with people who don't code.
Is vibe coding safe?
It's safe for prototypes and internal experiments, but risky in production without a review. The most common problems are database access rules that let users read each other's data and secret keys exposed in the browser. Both are fixable once someone goes looking for them.
Do I need to rewrite my vibe-coded app before launch?
Usually not. Most vibe-coded apps are standard React and TypeScript, often backed by Supabase, so the work is locking down data access, moving secrets to the server, handling payments properly, and adding tests, staging and monitoring. A rewrite only makes sense if the app has outgrown its original design.
Is AI generated code secure?
Not automatically. It can be secure, but it is written to make a feature work, and security gaps don't show up in a preview. Treat it like code from a quick but unsupervised junior developer: review it, test it, and check who can read each table before real users rely on it.
Portrait of Max Winter-Leinweber

About the author

Max Winter-Leinweber

Founder, Scryptic

Max is the founder of Scryptic and a full-stack developer with five years of experience building software for enterprise clients and startups. He builds MVPs for UK founders and takes apps made with no-code and AI builders through to production.

Planning an app?

Tell us what you want to build on a free call. You get straight advice on scope, stack, cost and timeline, then a written estimate before any work starts.

Book a discovery call
All 29 posts

MVP

How to build an MVP, week by week

How to build an MVP in one to two months, week by week: scoping, design, build sprints, launch week and the first month with real users, with checklists.

10 min read