Ready for real customers
What the map checks
We read your code for 23 of them today, as rules and not as an AI’s opinion. For Tests, we run your app on a copy. We do not test your live site. Nothing changes without your yes.
Safe
10 areas
Data access
Anyone on the internet could read, or change, the data your customers trust you with.
What the rules read today
- Database tables with no access rules, or with rules that let anyone, or any signed-in person, read or change every row.
- Views that hand out rows past the access rules of the table behind them.
- Public file storage: buckets anyone can download from, and storage rules that let strangers read or change files.
- Firestore rules that let anyone read or change your data, and database functions anyone can run with extra power.
Keys
Anyone who can read your code can use a key written in it as if they were you.
What the rules read today
- Secret keys written into your files: AI keys (Anthropic, OpenAI, Groq, xAI, ElevenLabs), Stripe secret keys, GitHub and Slack tokens, AWS keys, your database's secret keys, private keys and webhook signing secrets.
- A settings file kept with your code: it holds no secret today, but the next one added to it will be public.
Logins
Strangers could sign up without proving an email address, guess passwords all day, or take over an account.
What the rules read today
- Sign-up without email confirmation, passwords that may be short, and changing a password without asking for the old one.
- Sign-in tokens that stay valid for a very long time, and sign-in attempts allowed too many times in five minutes.
- Sign-in that may send people to any website, and your database's master key set up to be sent to every visitor.
- Sign-in code you wrote yourself: passwords kept exactly as typed, passwords hashed with MD5, SHA-1 or plain SHA-256, tokens never checked, guessable codes, cookies without their flags, and no limit on tries.
Access holes
One customer could see or change another customer's data.
What the rules read today
- Rules that let any signed-in person read every row of a table that holds personal rows.
- Rules that allow changes to rows but never compare a row's owner with who is asking.
- Server routes that read, change or delete a row by an id taken from the request, with no check of whose row it is.
Input safety
A stranger could type something that your app then runs or stores as if it were yours.
What the rules read today
- Database queries built from text a visitor sends, or a visitor choosing which database function is called.
- Pages that write a visitor's saved text back out as page code, so a visitor can put their own code into a page.
- Uploads with no limit on the size or the type of the file.
Cost guard
Strangers could spend your AI credit, and the bill would be yours.
What the rules read today
- An AI key or a payment secret named so that the app copies it into the page every visitor downloads.
- A paid AI call in a route that asks nobody who is calling and has no limit.
- A paid AI call with no ceiling on the length of the answer and nothing limiting what a visitor sends.
Parts
A package your app uses may have a published security problem, and nothing would tell you.
What the rules read today
- Looks up every package version your lockfiles pin in the public flaw database (OSV).
- Lists the ones with a published flaw, and says so when the makers have not published a fix yet.
Old runtimes
The version of Node, or of the framework, your app runs on can stop getting security fixes, and nothing would tell you.
What the rules read today
- A Node version your files ask for (package.json, .nvmrc, Dockerfile, build files) that its makers no longer fix, or will stop fixing within 90 days, with the day.
- A line of Next.js, Nuxt, Express or Vite that package.json names and its makers no longer fix.
- An app that never says which Node it runs on, so whoever runs it picks one. A note beside the tile, not a fault.
The dates are the makers' own, read on a day the check names. A version set only in your host's dashboard is not in the code, so the fix says the host may need the same change.
Browser protections
Another site could show your pages hidden inside its own, or read answers meant for a signed-in visitor.
What the rules read today
- None of the four browser safety headers set anywhere in the code: Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options and a frame protection.
- A server that answers any website's address, or every website with the visitor's login.
- A script loaded from another site, pinned to a version, with no fingerprint check.
A header your host adds in its dashboard is not in the code, so the rules say not set in the code, never not set.
Build robot
The robot that builds your app holds your secrets; a stranger's pull request or one careless line can turn it against you.
What the rules read today
- A build that starts on a pull request and runs the stranger's code with your secrets, or pastes a title, a comment or a branch name into a command.
- Build files that never say what the robot may do, so it gets whatever the repository's default gives it.
- Other people's actions used by a tag, which their owner can move, instead of a fixed version. Actions made by GitHub itself are said, not failed.
- No Dependabot or Renovate file, so nothing tells you when a part of your app has a fix.
Only GitHub Actions files are read. GitLab CI, CircleCI and Bitbucket Pipelines are not, and neither is a setting made on GitHub itself.
Works
4 areas
Tests
Nobody knows the app works from start to end until a real visitor has tried it.
What the visitor tests try
- The home page loads, shows something, and has no error on it.
- The sign-in page loads and has a sign-in form. It does not sign in.
- In an app with a sign-in, its signed-in pages (dashboard, admin, settings, billing and the like) stay locked to a visitor with no session.
- Nothing secret is served: no settings file or git file, and no secret key in the scripts the pages load.
- A harmless word sent in the forms and addresses we find comes back as plain text, and an outside address given to a link is not followed.
- A harmless word put in a page's address, and after the #, stays plain text on the page once its own scripts have run; it never becomes a part of the page.
- In an app built from SQL migrations, a second test account cannot read, change or delete the first account's rows, nor add rows in its name; routes that take an id give a row to its owner only.
Errors and uptime
Your app could crash or go down, and you would hear about it from your customers.
What the rules read today
- Server code that catches an error and does nothing with it.
- No error tracking set up in the app.
- No error page: nothing catches a page that crashes.
- No health address that an uptime monitor could ask.
Backups
If your database is lost or damaged, there may be no copy to bring it back from.
What the rules read today
- A database app with no backup of any kind in its code.
- A backup that stays on the machine that makes it, or is saved into the code repository.
- A backup in the code with no sign that a restore was ever tried.
- A database on a free plan may keep no backup of it, or delete it (Supabase Free, a Free Render database). The plan is in your account, so we ask which one, once, and quote the vendor's page.
A line in a document can satisfy this rule. It does not prove that a backup runs or that a restore works.
Speed
Pages load slowly, and visitors leave before they see anything.
What the rules read today
- Pictures sent to visitors at full size, and plain image tags with no size and no lazy loading.
- Code that asks the database one question for every row, or loads every row of a table with no limit.
- Files that download a whole library for a few helpers.
Legal
4 areas
Legal pages
Collecting people's details, tracking them or taking payment without the pages EU law expects leaves you open to complaints.
What the rules read today
- A privacy page, and a terms page where people can sign up or pay: whether each exists and is linked.
- Tracking tools loaded with no cookie-consent tool named anywhere in the code.
- Sign-up with no way for a person to delete their account.
- An imprint page, for apps written in German.
The rules read whether a page exists and is linked, never its words. This is not legal advice.
Personal data
Your users can ask for a copy of their data and for who else receives it, and an app that cannot answer leaves you open to complaints.
What the rules read today
- Sign-up that keeps a person's rows, with no way for the person to download them.
- A company your code names (analytics, mail, AI, crash reports, Supabase, Stripe) that your privacy page does not name; its processing agreement is yours to sign.
- A log call that is given a whole user, a request body, or an e-mail address or phone number.
Only the companies the code names and this check knows are matched to your privacy page. Your host, settings kept in a dashboard and apps outside JavaScript and TypeScript are not read. This is not legal advice.
Accessibility
People who use a keyboard, a screen reader or a zoomed screen cannot use your app, and the law in the EU may expect it to be usable by them.
What the rules read today
- Pictures with no alt text, form fields that nothing names, and buttons or links that hold only an icon.
- A page that does not say its language, and a viewport that stops people from zooming.
- A box that can be clicked but not reached by the keyboard, and a password or email field that refuses a paste.
- A style that switches off the ring showing where the keyboard is, with nothing to replace it.
Colour contrast and the size of touch targets need the live page and are not read, nor is what a screen reader says. The EU Accessibility Act does not reach a business with under 10 persons and EUR 2 million or less (Art 3(23), 4(5)). This is not legal advice.
Open-source licences
A part your app is built on can come with a licence that limits how you may sell it or run it, and you only find out when someone asks.
What the rules read today
- A part under a licence that may make you publish your own source or may not let you earn from the app (AGPL, GPL, SSPL, a non-commercial licence), or under none.
- Parts under a weak copyleft licence (LGPL, MPL and the like), named in one note.
- Parts whose licence is written in words that are no licence name, named in one note.
Only package-lock.json carries licences: an app that uses yarn.lock, pnpm-lock.yaml or bun.lock is not read for them. A licence may limit what you can do; whether it does is for you or a lawyer to say. This is not legal advice.
Money
1 area
Payments
Someone could get what customers pay for without paying, or a customer could be charged twice.
What the rules read today
- A payment-confirmation address that does not check who is calling, or is handed the wrong body so it turns real payments away.
- A payment that charges the amount the browser sent.
- A page that marks an order paid because of an address, not because money arrived.
- A Stripe payment created again on every retry, with no key that stops a double charge.
Reach
3 areas
Email
Your mail may land in spam, or not be sent at all.
What the rules read today
- Mail sent through a personal mailbox, or from a free-mail address.
- Sign-up, sign-in and password-reset mail sent from the built-in sender that is made for development.
- Mail with no plain-text version, and mail to a list with no unsubscribe link.
The code's side only; your domain's mail records (SPF, DKIM, DMARC) are not read.
Search and launch
People who look for you find a blank or unfinished listing, or nothing at all.
What the rules read today
- A missing page title or description, or a description left over from the starter.
- Links with no share picture, and a browser tab with no icon.
- No sitemap or robots file for search engines to read.
- A leftover tag or robots file that tells every search engine to stay away.
Marketing
You could launch and never know who came, or have no way to bring them back.
What the rules read today
- Nothing in the code counts your visitors.
- Visitors have no way to leave their email address.
- No page that says what is new.
- A front page that offers no next step.
Run
2 areas
Staging and deploys
A broken change can reach your visitors, with no safe place to try it first and no way to go back.
What the rules read today
- Nothing in your automatic build files runs your tests or your build before a change goes live, or a secret value is written in one.
- A database setup that is not in the code, so a copy or a restore starts from guesswork; and, among your newest migrations, a statement that removes or rewrites rows with no copy of them made first.
- No separate test copy of the app named anywhere in the code.
- A table your newest migrations make with no GRANT for your API's roles: from 30 October 2026 Supabase keeps it out of the API. A table already live keeps its access; your live grants are not read.
Your code can name a platform whose free plan has a limit (a paused project, a site that goes offline, no own domain). The plan is in your account, so we ask which one, once, and quote the vendor's page.
Support
A customer with a problem has nobody to ask, and one who forgets a password is locked out.
What the rules read today
- Whether a visitor has a way to reach you from the app.
- Where accounts have passwords: whether a visitor who forgets one can reset it.
Want to see it on your app?
Connect the code, and the map shows each area as checked, to fix, or not checked yet. We change nothing without your yes.