top of page

What Actually Breaks in Lovable Apps (and How to Check)

1 hour ago
4 min read

Specific to the stack Lovable produces — React, Vite and Supabase — and the five failures that come with it.


Lovable gets criticised in general terms and defended in general terms, and neither is much use if you have an app in front of you. The useful version is narrower. Lovable produces a particular stack, and that stack has particular weak points. They're consistent enough that when a Lovable repo arrives, there's a list to check before reading anything else.


Worth saying at the top: this isn't an argument against the tool. The output is standard React with Vite and Supabase behind it, synced to GitHub, and that's the most ordinary and handoff-friendly artifact of any of the major builders. When people ask which one to build on, this is usually the answer. These five are what comes with it.



Isometric Laptop Database Alert


1. Supabase policies left open


Lovable's tightest integration is with Supabase, which is a genuine strength — your database exists independently and survives you leaving. It also means the security boundary of your entire app lives somewhere Lovable doesn't fully manage on your behalf.


Row-level security in Supabase is opt-in per table. A table with it switched off is readable by anyone holding the public key, which is by definition in every browser that loads your app. And when policies do get created, they're often written to check that the requester is logged in rather than that the requester owns the row. That policy looks active in the dashboard and grants everyone access to everything.


This is the single most common finding in Lovable apps, by a distance. It's also the fastest to check: open the table editor, look at the RLS column, then read the policy text on anything holding user data.



2. The client is created once and shared


Lovable-generated apps typically instantiate the Supabase client at module level and import it everywhere. That's conventional and fine.


Where it causes trouble is in combination with client-side caching and asynchronous session restoration. On page load there's a window where the app holds cached data from a previous session and a user object that hasn't resolved yet. On a shared computer, or a browser where one person logged out and another logged in without a hard refresh, the app can briefly render the previous user's data before correcting itself.


Brief, but visible. This is the mechanism behind the intermittent "I saw someone else's data" reports that are impossible to reproduce on your own machine, because on your own machine there's only ever been one user.



3. Edge functions with no validation


When something can't run in the browser, Lovable reaches for Supabase Edge Functions. These run server-side, which is correct, and they're frequently written as though only your own frontend will ever call them.


So they don't check who's calling. They don't validate the shape of what arrives. They trust an ID passed in the request body rather than deriving it from the authenticated session. That last one is the serious version: an endpoint that acts on whatever user ID you send it is an endpoint anyone can point at anyone.


These are also where secret keys most often end up being used correctly and then, in a later iteration, get moved to the frontend to fix something. Worth checking the git history around any function that touches a service key.



4. Everything loads at once


Standard React with a Supabase query and no pagination produces a screen that fetches the entire table and filters in the browser. Built against thirty test rows, it's instant.


Lovable's output tends toward this because the prompt was "show the user's orders" and the simplest correct implementation is to select them all. Nothing in the loop surfaces that there'll eventually be four thousand. Add missing indexes on the columns you filter by every time, and the degradation is gradual enough that nobody attributes it to anything.


The tell is a list screen that's fine in testing and slow in month four.



5. No migrations, so the schema is frozen


Schema changes during building are made in the Supabase dashboard, directly against the live database. That's the fastest way to work and it's what the tool encourages.


The consequence arrives later. Once you have production data, there's no migration history, no way to test a schema change before applying it, and no way to reverse one. The database becomes the thing nobody wants to touch, which quietly caps what you can build next.


Of the five, this is the one that costs the most to fix late and the least to set up early.



What's usually fine


Since the list above is all problems, the balance is worth stating.


The component code is generally clean and readable. The routing is conventional. The GitHub sync is reliable and the export is genuine — you can point it at Vercel or Netlify and it runs. Styling is standard Tailwind rather than anything proprietary. A developer picking up a Lovable codebase knows where they are within twenty minutes, which is not true of every builder.


That readability is the reason Lovable apps are comparatively cheap to finish. The problems are in the layers the tool touches least, not scattered through the code.



The check, in order

If you have a Lovable app and half an hour:


Open the Supabase table editor. Check RLS is on for every table with user data. Read the policy text on each. Anything that only checks for an authenticated user is not protecting the row.


Log in as a second test account and walk the whole app. Then change a record ID in a URL. This catches both the policy problem and the caching one.


View source on your live site and search for service_role and sk_. Check the loaded JavaScript too, not just the HTML.


Look at your largest table and ask what the app does when it has a hundred times as many rows.


Ask yourself how you'd change a column type next month without losing data. If there's no answer, that's the migration gap.


Four of the five are things you can verify yourself in an afternoon. The fifth — the edge functions — needs someone to read the code, which is where AI app rescue starts on every Lovable project we take on.




Not sure where your app stands?

We read the codebase and send you a written list of what's actually missing — the specific files behind each finding. No obligation to hire anyone.







Comments


bottom of page