Purple gradients, glowing dark mode and emoji icons are the quick answer to how can you tell if an app is vibe-coded, and the weakest one, because taste is the cheapest thing in an app to repaint. The sturdier tells are defaults the tools document themselves: a lovable.app or base44.app address, a Vite + React browser tab, sign-up emails that reach nobody outside the app’s own team.
How can you tell if an app is vibe-coded? Start with what the builders document
An app is usually vibe-coded when its own address or repository carries a builder’s documented defaults: a lovable.app, base44.app or replit.app address, or bot-authored commits. Visual style hints at it; the documented defaults show it, and none of them says whether the app is safe.
If someone built the app for you, the accounts and repository behind these tells belong in what a proper developer handoff includes. Every address, file and header below was read from the vendor’s own documentation on 21 October 2026; no app was opened and nothing was run against a live site.
| Builder or host | Default published address | What the repository holds |
|---|---|---|
| Lovable | [url-subdomain].lovable.app, and the docs say there is currently no way to remove it | Commits authored by lovable-dev[bot]; repositories private by default on every plan; a lovable-fallback branch after a synced branch is deleted |
| Base44 | myapp.base44.app, live from the moment the app is created | @base44/sdk in package.json and a functions/ folder beside src/; under two-way GitHub sync, entities stay in Base44 |
| Bolt | A random bolt.host name, created at first publish | Not stated in Bolt’s docs |
| Replit | <your-live-app-subdomain-name>.replit.app | .replit and replit.nix, hidden by default in Replit’s file tree |
| Vercel | Generated per commit, branch, CLI deploy or team author; the branch one carries the git branch name | A vercel.json, vercel.toml or vercel.ts file, when the project keeps its settings in a file |
| Netlify | [name-of-your-site].netlify.app | A netlify.toml file, when the site keeps its settings in a file |
The address column comes from Lovable’s publishing docs, Lovable’s custom domain page, Base44’s custom domain guide, Bolt’s publishing guide, Replit’s custom domains page and Netlify’s domains glossary. The Base44 cell comes from its project structure page.
Vercel and Netlify are hosts, not builders: their address says where the app runs, never how its code was written.
How to tell if a website is vibe coded: the address bar, the browser tab and the email
A website is likely vibe coded when it still carries a builder’s defaults: a builder subdomain in the address bar, a Vite + React title in the browser tab, or sign-up emails that never arrive. Each takes minutes to check, and most take little longer to remove.
- 01 Read the address bar, and the address of any link you were sent: look for a builder subdomain or a host's generated address.
- 02 Read the title in the browser tab on the home page.
- 03 Sign up and read the email that arrives: note who sent it, and whether a second address you own receives one too.
- 04 Open the page source and look for a generator meta tag.
The address does most of the work. Vercel’s generated URLs reference gives a branch deployment the shape <project-name>-git-<branch-name>-<scope-slug>.vercel.app, meant for sharing a branch’s latest changes with team members during review. So an address with -git- in it follows one branch’s latest deployment, and the same page lists the project’s production URL separately. On Lovable, published sites have no fixed expiry date, while share preview links expire after seven days by default, so an old lovable.app link that still loads is unlikely to be a share preview.
Apps started from the create-vite React template begin with <title>Vite + React</title> in index.html. A live app still showing it hints that nobody edited the file; it proves nothing alone.
The sign-up email shows itself through behavior. Supabase’s custom SMTP guide says its default auth email server is “not meant for production use”, is set to 2 messages per hour, and refuses to deliver to addresses outside the project’s team. Sign-up emails that never reach anyone outside the project’s team, or stop after two an hour, are that default seen from outside. Resend’s Node.js quickstart uses onboarding@resend.dev in its example and says the address “is for testing only”, and Resend’s error reference adds that this test sender delivers only to the Resend account’s own address, so a sign-up email that never arrives can be that tutorial sender left in place.
None of the seven vendor pages behind the address column documents a generator meta tag on published apps; that describes those pages on 21 October 2026, not every builder.
If you want to check if a website is made with AI, these four checks name the builder and the host, never the person who typed the code. None of them needs access to a vibe coded website’s code: each reads only what any visitor’s browser already shows. The same checks tell you if a game is vibecoded when it runs in the browser.
Is it vibe coded? What a yes changes for an app you paid for
A yes names how the app was made, not whether it works. The question that matters for an app with customers is whether one signed-in customer can reach another customer’s data, and no tell on the outside answers it.
In June and July 2026 we audited 21 third-party apps, and 7 of them had confirmed cross-user or cross-tenant authorization failures, where a logged-in user could read or write another customer’s data. We chose those apps ourselves, so the figure describes them and not apps in general.
On an app you own, you can test this without code. Make two accounts, sign in as the second, open a record of the first by its link or id, and expect a refusal; a page showing the first account’s data is the finding. The control that should refuse it is enforcing permission on every route.
If the app is vibe-coded and customers’ data or payments depend on it, a free audit is where we go over what you found with you and which check to run first. In the Production Hardening Sprint, deliverable 1.4, data isolation across every table, is verified this way: run read and write tests as anonymous users, different roles, and separate tenants.
The network tab, the response headers and the repository
The network tab and the response headers are the sturdiest tells, because the host sets them and the owner rarely changes them. Requests to a supabase.co project or to firestore.googleapis.com name the backend, and headers such as server: Vercel name the host.
Open the browser’s developer tools, choose the Network tab and reload: every address the page talks to is listed there. Supabase’s API guide puts its REST API at https://<project_ref>.supabase.co/rest/v1/, so those requests name Supabase and carry the project’s reference in the address. Seeing a project URL and a key in them is expected; whether a visible Supabase key is a problem turns on which key it is. Firestore’s REST API guide says all its REST endpoints sit under https://firestore.googleapis.com/v1/, with paths that start /projects/YOUR_PROJECT_ID/. Either backend names the service, not the way the code was written: hand-written apps use them too.
Headers name the host without any of the app’s code being involved. Vercel’s response headers reference lists server: Vercel, which “Shows where the request came from”, x-vercel-id, which lists the Vercel regions a request hit, and x-vercel-cache, which reports the cache status. The same page says you can read them in the browser’s dev tools or with curl -I, and that a proxy such as Cloudflare can override the server header.
In a repository, Replit leaves two files. Replit’s workspace configuration page says .replit controls the app’s behavior in the toml format and that Replit uses Nix for packages, which is what replit.nix holds; both stay hidden until you choose Show hidden files. The Lovable row of the table comes from Lovable’s GitHub integration docs, which add that raw git log output shows the author as gpt-engineer-app[bot], an earlier name for the same account. The private default matters too: being told there is no repository to look at says nothing about how the app was built. Reading the code itself for signs a model wrote it is a separate job, covered under telling whether code was AI generated.
What is my app built with? Checkers and the card statement
Lookup tools read a public page from the outside. BuiltWith says it covers 127,883+ internet technologies, including analytics, advertising, hosting and CMS, and Wappalyzer says it looks for public signals such as HTML code, scripts, headers and cookies. A vibe code checker such as vibe0’s Vibe Check takes a public URL and groups what it finds into declared use, build traces, interface patterns and copy patterns, and its own page says the result “does not establish authorship, quality or security”.
None of these tools names the agent that typed the code, and none sees what runs on the server. An owner has a faster honest route: the monthly charges. Every paid service bills somebody, and the card statement names the ones the app runs on.
Vibe coded UI signs: gradients, glows and default components
Visual signs of a vibe-coded app are habits of the tools’ defaults: purple gradients, dark mode with decorative glow, emoji used as icons, a card around every block. They are real, and they are the weakest evidence, because a designer can change all of them in an afternoon.
The Fountain Institute’s list, “7 Signs a UI Has Been Vibe Coded”, names neon color palettes, dark mode with decorative glow effects, emojis used as icons, purple gradients on everything, cards for every block of info, multicolored side tabs and status dots that mean nothing. The same article notes that purple-to-blue gradients appear in the marketing materials for Notion, Linear and Vercel, so a gradient alone cannot separate a builder’s default from a design team’s choice. One shared default is documented: Lovable’s own glossary describes Tailwind CSS as the framework “used to style Lovable projects”.
An owner who finds their own interface generic is noticing something real. It is a marketing cost, paid in sign-ups, and it says nothing about whether the app keeps one customer’s records away from another.
What none of this tells you
Each tell an outsider can see names a method, not a result. An app can show all of them and still work well, or show none and still let one customer read another’s records; the only way to know is to test what the app does with a second account.
| Tell | What makes it disappear |
|---|---|
| The look of the interface | A designer’s afternoon, or the next prompt |
The Vite + React browser tab | One line in index.html |
| The default published address | A custom domain, though Lovable’s docs say its project URL stays |
| The sign-up email | A real mail service, which Supabase’s docs urge owners to set up anyway |
| Requests to a backend host | Moving off that backend, or a proxy or your own domain in front of it |
| The host’s response headers | Rarely the owner, since the host sets them, though a proxy can override them |
The easy end of the table is taste, and the hard end is infrastructure. Neither end tests anything, which is why the problems a vibe-coded app hides stay hidden through every check above, and why checks you can run without reading code start from what the app does rather than how it looks.
What to do with the answer
The next step depends on the worry that started you looking.
| What you were worried about | The next step |
|---|---|
| The person you paid | A conversation about accounts, access and what was handed over |
| Customer data or payments | The safety question, answered on its own terms |
| It will stop working at the next prompt | A test that fails when it breaks |
The conversation, and what comes after it, is the subject of taking over an app someone else built. For customer data and payments, read whether vibe-coded apps are safe rather than inferring it from an address bar. For the last worry, the durable answer is a smoke test that catches a broken app every time someone changes it.
When the answer has to satisfy a customer, a buyer or an investor, the useful evidence is a record for each check, not a guess about how the app was built. In the Production Hardening Sprint, deliverable 13.1, the production readiness report, is verified this way: account for all 123 IDs; keep failures visible until resolved and explain genuine non-applicable items.
Common questions about spotting a vibe-coded app
What makes an app look vibe coded?
Two kinds of default make an app look vibe coded: the tools’ visual habits and the builder settings nobody changed. The visual habits include purple gradients, decorative glow on dark panels, emoji standing in for icons and a card around every block of text. The unchanged settings include a lovable.app subdomain, a Vite + React tab title and sign-up mail that never arrives. Of the two, the visual habits are the weaker sign, since they are the easiest to restyle.
How to make an app not look vibe coded?
Replace the defaults on your own app: point a custom domain at it, set your own title and icon, connect a real email sender and pick a visual style on purpose. The host’s headers and the backend’s addresses usually stay, and on Lovable the original project URL cannot currently be removed, though you can set your own domain as the primary one. None of these changes alters what the app does with customer data.
How can I find out who developed an app?
Usually you cannot, from the outside. An app store listing names the account the app was published under, and a domain record may name a registrant, but neither records who wrote the code. A repository’s commit history comes closest: on Lovable, commits the builder makes are authored by lovable-dev[bot] and co-attributed to the workspace member who triggered them.
When does it matter that an app was vibe coded?
It matters once customers’ data or payments depend on the app, because the tells show how it was made and not whether one customer can open another’s records. AxonBuild runs a free audit, where we talk through with you what the tells mean for your customers’ records.
Wondering what your app was really built with?
Knowing which builder made your app is the easy part. The harder question is whether anyone made sure it holds up with real users and real data. On the audit, we look at the app with you, point out the risks we can see, and help you choose what to ask your builder next.
Book a free audit →
Free · 30 minutes · No code access needed