By the time a developer ships a working app from Bolt.new in an afternoon, the question shifts. The generator produced something that runs in a browser. The harder question is whether the same code, the same dependencies, and the same backend wiring are safe to put in front of real users with real data.
Short answer
Bolt.new generated code is production-runnable, not production-ready. The default output works, but the same patterns that make Bolt.new fast (one-shot scaffolding, full npm dependency pulls, direct API integrations) ship a recognisable set of holes: hardcoded keys in the client bundle, Supabase Row Level Security disabled, no input validation on serverless functions, and a dependency tree built from whatever the AI called for that day. Each of those is fixable. None are caught for you.
What you should know
- Bolt.new compiles a real codebase. The generator emits a working Vite or Next.js project with real npm dependencies, real client and server code, and real environment variable handling. The output behaves like any other JavaScript project at audit time.
- The default integration patterns prefer speed over isolation. Bolt.new often calls third-party APIs (OpenAI, Stripe, Supabase) directly from the client, with the key handed in as a Vite environment variable. That key ends up in the published bundle.
- Supabase Row Level Security is opt-in. The Supabase anon key is publicly readable by design; the protection layer is RLS policies on each table. Bolt.new rarely generates those policies.
- The npm tree reflects what the AI thought it needed. A Bolt.new project commonly carries 200 to 600 transitive dependencies. Some are well known. Some were called for by name based on a model's recall and may be typosquats or recently registered look-alikes.
- Source maps and exposed env strings end up in the deploy. Vite ships source maps by default and inlines any
import.meta.env.VITE_*variable into the bundle. Anything prefixedVITE_is public.
What does Bolt.new actually generate, and why does it matter for security?
Bolt.new is an AI scaffolding tool that produces a working web application from a prompt. The output is a real npm project, typically Vite plus React, with a package.json, a lockfile, and direct integrations to Supabase or other backends-as-a-service. From a security stance, that means the same audit surface as any other modern frontend: a client bundle, a set of public environment variables, a backend configured by the developer, and a long dependency tree.
The relevant primary documentation is the npm registry's audit guide, which is explicit about scope: npm audit reports known vulnerabilities from the advisory database. It does not flag malicious packages that have not yet been catalogued. A Bolt.new project that passes npm audit cleanly can still contain a freshly published typosquat. That distinction matters because AI scaffolding tools have a documented tendency to call packages by name based on a model's training-time recall, sometimes with hallucinated or stale names that attackers register proactively.
Where do most Bolt.new production failures happen?
In practice, the same five surfaces account for most of the production issues developers report after shipping a Bolt.new app.
The first is keys in the client bundle. Anything prefixed VITE_ in the source ends up in the published JavaScript. Stripe secret keys, OpenAI keys, and Supabase service-role keys placed in .env with the wrong prefix become public. The fix is to put paid-API keys behind a serverless function and only expose anon-level keys to the client.
The second is Supabase Row Level Security. With RLS disabled, the anon key allows any visitor to read or modify any row. The Supabase Row Level Security documentation is direct on the point: RLS is opt-in per table, and a project with public tables and no policies has no access control at the database layer. Bolt.new does not write those policies for you.
The third is missing input validation. AI-generated serverless functions tend to trust the body they receive and pass values directly to downstream services. That includes paid APIs (OpenAI billing exposure), database writes (injection via JSON shape), and Stripe operations (amount tampering).
The fourth is the npm dependency tree itself. Recent supply-chain incidents documented in The Hacker News reporting on a malicious npm package using a hidden prompt show a pattern in which a typosquatted package (in that case, eslint-plugin-unicorn-ts-2) ships a post-install script that exfiltrates environment variables to a webhook. The package included a fragment of text aimed at deflecting AI security scanners. By the time it was flagged, it had been downloaded close to nineteen thousand times. A Bolt.new project that runs npm install without further audit picks up whatever the AI chose, including any cousin of that pattern.
The fifth is the absence of security headers. The deployed bundle ships without a Content Security Policy, without X-Frame-Options, and without Strict-Transport-Security. These do not block exploitation by themselves, but their absence widens the attack surface.
How do I audit the npm dependency tree of a Bolt.new project?
The honest answer is that no single command audits a dependency tree for malicious packages. The npm audit command reports known CVEs against the registry's advisory database. That is necessary, not sufficient. A practical audit combines several passes.
The starting point is npm ci, run from the lockfile, in a clean checkout. The OWASP NPM Security Cheat Sheet explains why this matters: npm install will resolve fresh versions; npm ci installs exactly what the lockfile records. For an audit, you want a frozen, reproducible tree.
The next pass is npm audit --omit=dev for the production tree and a separate npm audit for the full tree. Reading both outputs gives a picture of where vulnerable code lives. If a known vulnerability sits only in devDependencies, the user-facing build is unaffected; the build pipeline still warrants attention.
A third pass the OWASP cheat sheet recommends is to set ignore-scripts=true in .npmrc. Post-install scripts are the most common malicious payload vector. Disabling them by default and using an explicit allowlist (such as @lavamoat/allow-scripts) for the small number of packages that genuinely require build steps removes a class of attacks the audit command cannot see.
A fourth pass is to verify each direct dependency by hand. The npm view <package> command shows the publisher, the publish date, the maintainers, and the linked repository. A new dependency published last week, with no GitHub repository, and a name that almost matches a popular package, is the typosquat shape.
For the dependency tree of a typical Bolt.new project, the time cost of the four passes is in the order of one to two hours and pays for itself the first time it catches a problem package.
What does a real pre-ship Bolt.new security checklist look like?
The five-gate pre-submission model (Permissions, SDKs, Storage, Network, Build) adapts cleanly to Bolt.new. Each gate is a yes or no question the developer answers before deploying.
| Gate | Question | Bolt.new default | Production-ready |
|---|---|---|---|
| Permissions | Does any client call a paid API directly? | Yes, via Vite env var | No, proxied through a serverless function |
| SDKs | Has every direct dependency been verified with npm view? | No | Yes, publisher and repo confirmed |
| Storage | Does every Supabase table have an RLS policy? | No (RLS off) | Yes (RLS on, policies per role) |
| Network | Does the deployed app send CSP, HSTS, and frame-ancestors headers? | No | Yes (set at the host or proxy) |
| Build | Does the deployed bundle contain source maps or .env strings? | Often yes | No (source maps excluded, env audited) |
The table is not exhaustive. It is the minimum surface a developer can carry in their head while shipping. PTKD.com (https://ptkd.com) is one of the platforms focused on running this kind of pre-submission scan on AI-coded builds, including bundles produced by Bolt.new, against OWASP MASVS-aligned controls before the deploy goes live. For solo developers without a security review process, an external scan is the practical substitute.
What to watch out for
- A passing
npm auditis not a clean dependency tree. It only reports catalogued CVEs. Recent malicious packages routinely slip past it. - A Vite environment variable prefixed
VITE_is public. The Vite documentation states this explicitly; review every.envline before deploy. - A Supabase anon key in the client is normal, but only with RLS. Without RLS policies, the anon key allows full table access to any visitor.
- Deploying a hot-fix commit straight from the AI is the highest-risk pattern. Bolt.new will happily generate new code that bypasses the safety changes a developer already added. Each prompt is a new audit surface.
- A serverless function with no authentication is a public endpoint. Treat it as such when wiring AI or payment calls behind it.
Key takeaways
- Bolt.new generated code is a real codebase, not a sandbox. Treat the audit surface the same as a hand-written project.
- The recurring failure pattern is keys in client bundles, RLS off, no input validation, and an unaudited npm tree. Fixing those four removes most of the practical risk.
- The dependency tree deserves a manual pass. The
npm auditcommand catches CVEs;npm viewandignore-scripts=truecatch the rest. - Some teams outsource the pre-ship scan to a platform like PTKD.com (https://ptkd.com). For solo developers shipping AI-coded apps to a real user base, an external scan against OWASP MASVS-aligned controls is a calm alternative to building an in-house review.
- Production-ready is a checklist, not a setting. Bolt.new gets you to a running app. The remaining gap is the audit you run before the first real user lands on it.




