Is your v0 app production-ready?
By Aakshar Garg, Founder, Scalable Systems · Last reviewed
the short answer
The interface usually is. The server side is where to look. Next.js Server Actions are invokable endpoints, and Next.js's own documentation says to verify authentication and authorization inside every one of them — even when the form is only rendered on an authenticated page. Anything prefixed NEXT_PUBLIC_ is inlined into the JavaScript sent to the browser.
v0 is very good at the part that's visible: components, states, layout, accessible defaults. That's also why v0 apps tend to fail in one specific place — the moment the generated interface starts writing to a database, the security model has to be added by someone, and a form that only renders for signed-in users is not a security model.
What we find in v0 apps
| What breaks | What you'd notice |
|---|---|
| A Server Action with no authorization checkcritical | Anyone who can reach your site can invoke it directly — not just the people looking at your form. Deleting or updating another user's record is a request, not an exploit. |
A secret in a NEXT_PUBLIC_ variablecritical | The value is compiled into the browser bundle at build time and is readable by anyone who views source. |
| No ownership check on a dynamic routecritical | /orders/1043 renders whoever's order 1043 happens to be, because the page fetches by id and nothing compares it to the signed-in user. |
| Validation only in the componenthigh | The UI enforces the rules and the server accepts whatever it's sent, including values your form would never produce. |
| Unbounded fetching or renderinghigh | A page that re-fetches on every interaction, or renders dynamically when it could be cached. The bill grows faster than the user count. |
| No rate limiting on public actionshigh | A contact form or signup action that can be called in a loop, at your expense. |
Is v0 production-ready?
The front-end code v0 generates is generally production-quality. Whether the application is production-ready depends on the server side that surrounds it: authorization inside every action, ownership checks on every route that takes an id, and validation that runs where the user can't edit it.
Are Next.js Server Actions secure by default?
No, and Next.js says so directly. Its documentation carries a warning to always verify authentication and authorization inside each Server Action, even if the form is only rendered on an authenticated page. A Server Action is a callable endpoint — rendering conditions in your UI don't restrict who can call it.
This is the single most common critical finding in generated Next.js apps, and it's a two-line fix per action: load the session, check the user is allowed to do this specific thing to this specific record, then proceed. The trap is that the app looks and behaves correctly without it.
v0 built my UI — what's usually missing?
Three things, in order: authorization on the server, ownership checks when a page or action takes an id, and server-side validation. All three are invisible in the browser, which is exactly why a working app can be wide open.
It's worth being clear that this isn't a v0 defect — it's a division of labour. You asked for an interface and got a good one. Nothing in the request said "and make sure user A can't delete user B's invoice".
Is it safe to put my API key in a NEXT_PUBLIC_ variable?
Only if the key is meant to be public. Next.js inlines NEXT_PUBLIC_ values into any JavaScript sent to the browser at build time, replacing the reference with the literal value. Variables without the prefix are only available on the server, which is where anything privileged belongs.
One consequence people miss: because the value is frozen at build time, promoting the same build between environments carries the build-time value with it. If you rotate that key, you have to rebuild.
Why is my Vercel bill going up faster than my users?
Usually rendering and fetching choices rather than traffic. Pages rendered dynamically that could be cached, data re-fetched on every interaction, or a loop that calls a paid API per row all scale with requests instead of customers.
This is the cheapest layer to audit and often the most immediately satisfying, because the fix is usually caching something that never needed to be live.
What should I check before launch?
Open every Server Action and confirm each one checks who is calling and whether they're allowed to touch that record. Then grep your code for NEXT_PUBLIC_ and make sure nothing privileged is behind it. Then walk the seven layers below.
The seven-layer production check
Every audit we run walks the same seven layers, in this order. Each one is a question you can answer about your own app today — no tooling required.
- 1
AccessCan a stranger reach something they shouldn't?
authentication, session handling, ownership checks on every route
- 2
TenancyCan one customer see another customer's data?
row-level security, tenant scoping, IDOR on every id in a URL
- 3
SecretsWhat's shipped in the browser that shouldn't be?
keys in the client bundle, service-role credentials, token scope
- 4
Money pathsCan a customer be charged twice — or not at all?
idempotency, webhook retries, payment state reconciliation
- 5
Load and costWhat happens at a hundred times this traffic, and what's the bill?
N+1 queries, missing indexes, unbounded jobs, runaway spend
- 6
ObservabilityWould you know it broke before a customer told you?
error tracking, structured logs, alerting on the paths that matter
- 7
RecoveryIf the data went wrong today, could you get it back?
backups you've actually restored, reversible migrations, rollback
Sources
Every claim above about a third-party tool was checked against that tool's own documentation on July 26, 2026. These products change fast — if you spot something out of date, tell us.
Related guides
Want someone to actually check?
We audit AI-built apps against all seven layers and hand back a report in plain English — with the technical detail underneath for whoever fixes it. Startup-friendly pricing, scoped to your project.
Book an Audit