Start with who can read your data
Most Lovable apps keep their data in a Supabase-style PostgreSQL database, either Lovable Cloud or a Supabase project you connected. The browser talks to that database with a public key that anyone can find in the page's code. What stops one customer from reading another customer's records is row-level security: a policy on each table that says which rows a signed-in user may read and change.
When those policies are missing, the public key is enough to read or edit the table. In 2025 a researcher checked 1,645 apps from Lovable's showcase and found about 170 with tables exposed this way (CVE-2025-48757). Lovable now runs a security scan before you publish, and it flags tables without policies. A policy that exists is not the same as a policy that is right, though, and the scan cannot know your business rules.
Check each table yourself:
- Row-level security is on for every table that holds user or business data.
- Each policy says who may select, insert, update and delete, not just who may read.
- Sign in as two different customers and try to open each other's records by changing an ID in the address or the request.
- Admin actions are checked in the database or on the server, not only hidden in the interface.
Keep secrets out of the browser
Anything in the frontend code is public. Secret keys for Stripe, OpenAI or your email provider belong in server-side functions, and the database's service key, which bypasses every access rule, must never reach the browser.
If a secret key was ever in the frontend or in a public repository, rotate it rather than delete the line. Old versions of the code stay in the history and in copies people have already downloaded.
Sign-in, accounts and roles
Sign-up works in the preview, then fails in production because the redirect address still points to the preview domain. Walk through every account flow on the real domain: sign-up, email confirmation, password reset, sign-in with Google or another provider, and deleting an account.
Roles deserve their own test. If your app has admins, staff or several customer types, decide what each one can do and check it on the server. A button that is hidden from a user can still be called by them.
Email that actually arrives
Confirmation and password-reset emails are often the first thing to break with real users. The email service built into a backend is usually rate-limited and meant for testing. Send from your own domain through a proper email provider, and set up the SPF, DKIM and DMARC records that tell inboxes the mail is really from you.
Then test with real addresses at Gmail and Outlook, including the spam folder, before launch day rather than after the first support ticket.
Payments that match access
Grant access from the payment provider's webhook, not from the page a customer lands on after paying: people close tabs, and pages can be opened directly. Verify each webhook's signature, and make sure a webhook that arrives twice does not create two subscriptions or two credit top-ups.
Test the paths that are easy to forget: a failed renewal, a refund, a cancelled subscription and a card that needs extra authentication. Each one should change what the customer can do, and nothing else.
A way back: environments, backups and deploys
Builders make it easy to change the live app with one prompt, and that is the risk. Keep the code in a GitHub repository, use a separate development database, and put every database change in a migration file that can be reviewed before it runs.
Turn on backups for the production database and try a restore once, so you know it works and how long it takes. Take a fresh backup before any change to the database structure, whether you make it or the builder does.
Know when something breaks
Real users find errors you never saw. Add error tracking to the frontend and the server functions, keep logs you can search, and set an alert for failed payments and failed emails. A slow page is often a query without an index or a list that loads every row; both show up once there is real data.
Keep it, fix it or rebuild it
Most apps do not need a rewrite. If the data model is sound, the usual work is access rules, secrets, account flows, payments and a deployment pipeline, and the rest of the code stays. A rebuild of one part, often payments or permissions, is common. A full rebuild makes sense when the data model itself is wrong, for example when every customer's data sits in one table with no owner.
A short code review answers that question before you spend money on fixes. It should end with a ranked list of risks and a fixed price for the ones that must be solved before launch.
Frequently asked questions
Can a Lovable app handle real users?
Yes, once the basics around it are in place: database access rules, secrets on the server, working email, payments driven by webhooks, backups and error tracking. The builder does not decide those for you.
Does Lovable's security scan make my app safe?
It catches common misconfigurations, such as tables without row-level security. It cannot know your business rules, so you still need to test what each type of user can see and change.
Do I have to move off Lovable to go to production?
No. Many teams keep the code synced to GitHub, review changes there and keep using the builder for new ideas. Hosting can stay with Lovable or move to your own account.
How much does it cost to make a Lovable app production-ready?
With us, usually $4,500–12,000 over two to five weeks, depending on payments, personal data and the number of user roles. A review comes first, then a fixed quote for the fixes.
Get a fixed price for your project
Book a 30-minute call. If the scope is clear, you get a written fixed quote within one or two business days.