Skip to main content
AttributeX AI

Bolt.new Production Problems: 6 Fixes Before Launch

12 min read

You burned through 2 million tokens and $1,200 in Bolt.new credits to get your app looking right. The WebContainer preview works. The flows click through. You hit "Download" or "Deploy to Netlify" and ship the link to your first ten beta users. Within a day, three of them cannot log in, one of them triggered a 500 error that took down the whole app, and your database has a test row sitting next to a real customer's payment record.

This is the gap between what Bolt.new builds and what a paying customer needs. Bolt.new is a prompt-to-app generator running inside StackBlitz's WebContainer — a browser sandbox that simulates a Node environment. That sandbox is great at producing a runnable prototype in 20 minutes. It ships almost nothing you need to charge someone money.

We have audited ten Bolt.new projects for funded startups in the last quarter. The missing pieces are identical across all of them. Here is exactly what Bolt.new leaves out, and the six fixes you need before your first paying customer.

Bolt.new is a prototype generator, not a deployment pipeline

Before the criticism: Bolt.new is legitimately impressive. Prompt-to-running-Vite-app in a browser tab, with hot reload, is a real engineering achievement. For validating that your idea renders as a working product, it is faster than any alternative.

But the WebContainer runs in your browser, not on a server. It has no persistent disk. It has no production-grade database. It has no background workers. It has no rate limiter. When Bolt.new "exports" your app, it hands you a zip of files that run locally — not a system that survives contact with real users. The failure mode is consistent: token burn peaks during the prototype, the export looks correct, and everything that matters for production was never in scope.

The 6 fixes Bolt.new exports need before paying customers

1. Real hosting with a real database (not SQLite in a container)

Bolt.new defaults to in-memory SQLite or a file-based database sitting next to the app code. This is fine in WebContainer because the container is ephemeral — the prototype is the database. The moment you deploy to Netlify, Vercel, or Railway, that database either disappears on every cold start or gets wiped on every deploy.

The exported package.json usually looks like this:

{
  "dependencies": {
    "better-sqlite3": "^11.0.0",
    "express": "^4.19.2",
    "drizzle-orm": "^0.36.0"
  },
  "scripts": {
    "start": "node server.js"
  }
}

The fix is not complicated but it is not free either. You need a managed Postgres (Neon, Supabase, or Railway Postgres), a connection pooler (PgBouncer or Neon's built-in), and a migration framework. Replace better-sqlite3 with pg or postgres, swap the Drizzle adapter, and rewire every query that depended on SQLite-specific behavior — INTEGER PRIMARY KEY AUTOINCREMENT becomes SERIAL or IDENTITY, datetime() becomes NOW(), json_extract() becomes ->>.

Budget 3-5 days for the database swap on a medium-sized app. Most of it is catching queries that silently returned wrong results in Postgres because SQLite's type coercion is looser.

2. Database migrations that actually exist

Bolt.new evolves your schema in-place during prompting. You say "add a subscription table" and it runs CREATE TABLE in the WebContainer's SQLite file. There is no migration history. There is no rollback. There is no diff between "schema as of yesterday" and "schema today."

Export the project and you get the current schema, but no way to reproduce it against a fresh database and no way to apply schema changes after the first deploy without manually running SQL. The next time you prompt Bolt.new to "add a status field to orders," you will have a new column in the export but no migration file that any production database can apply.

Fix: set up a migration toolchain before your first deploy. Drizzle Kit, Prisma Migrate, or node-pg-migrate all work. Generate an initial migration from the current schema, commit it, and enforce a rule that every schema change creates a new migration file. We also add a CI check that blocks PRs which modify schema.ts without a corresponding migration.

3. Authentication that is not glued together with placeholder JWTs

Every Bolt.new app we have audited has one of three auth patterns, all broken for production:

  1. A hand-rolled JWT implementation with jsonwebtoken and a hardcoded secret in an env file
  2. A Supabase client with the anon key in the frontend and no RLS policies on any table
  3. A "demo login" route that accepts any email and returns a session token

The hardcoded JWT pattern is the most common. The generated code looks like:

// server/auth.js — what Bolt.new ships
const JWT_SECRET = process.env.JWT_SECRET || "dev-secret-change-me";
export function signToken(user) {
  return jwt.sign({ id: user.id, email: user.email }, JWT_SECRET);
}
// No expiration, no refresh, no revocation, no password reset flow

Password reset is missing. Email verification is missing. OAuth callbacks point at localhost. Session revocation does not exist. Rate limiting on login endpoints does not exist, so credential stuffing against your first 100 users is trivial.

The fix is to replace the auth scaffolding wholesale with a real provider — Clerk, Auth0, Supabase Auth with RLS, or WorkOS — and wire it into every protected route and every database query. This is not a 2-hour task. Getting auth right in a Bolt.new export takes 5-8 days because the placeholder patterns are spread across the codebase.

4. Rate limiting and abuse protection on every public endpoint

Bolt.new generates API routes with zero rate limiting. Your /api/chat endpoint that proxies to OpenAI has no per-user limit, no global limit, and no cost cap. The first time a scraper or a misconfigured script hits it, your OpenAI bill runs up $200 in an hour. Your /api/signup endpoint has no captcha and no velocity check, so a bot can create 10,000 accounts in 20 minutes.

The missing layer looks like this in a working production app:

// lib/rate-limit.ts — what a production export needs
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

export const apiLimiter = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, "10 s"),
  analytics: true,
});

// In every public route handler:
const { success } = await apiLimiter.limit(identifier);
if (!success) return new Response("Rate limited", { status: 429 });

You also need a circuit breaker around every paid third-party API (OpenAI, Anthropic, Stripe, SendGrid) that stops calling when hourly spend exceeds a threshold. Bolt.new will never generate this because the WebContainer has no concept of hourly spend.

5. Environment variables, secrets, and .env hygiene

Bolt.new exports put API keys in .env files that get committed to the zip. We have seen OpenAI keys, Stripe live keys, and database URLs shipped inside exported projects. When founders upload the export to GitHub to hand off to a developer, those keys land in public repos within an hour.

Beyond the secret-leak problem, the env var structure is inconsistent. The frontend expects VITE_API_URL in one place and import.meta.env.API_URL in another. Server code reads process.env.DATABASE_URL in routes but hardcodes the connection string in a seed script. Half the variables have no fallback and no validation, so a missing env var produces a cryptic undefined is not a function crash at runtime instead of a clean startup error.

Fix: rotate every secret that appeared in any Bolt.new session, adopt a schema-validated env loader (zod + envsafe or @t3-oss/env-nextjs), and move secrets to your hosting platform's env UI. Never again commit .env to a repo that might leave your laptop.

6. Error handling, logging, and a working 500 page

Bolt.new apps throw uncaught exceptions into the void. No Sentry. No structured logs. No request IDs. When a user tells you "the page broke," you have no way to correlate that report to anything server-side. The default Express error handler dumps stack traces to the client — leaking file paths, dependency versions, and sometimes environment values — and the default Vite/SvelteKit error pages show the framework's dev overlay in production.

The production baseline: Sentry (or Axiom, Logtail, Baselime) installed on both client and server, a global error boundary that logs to the monitor and shows a branded 500 page, structured logs with request IDs on every API route, and uptime monitoring (Better Stack, Checkly) hitting /api/health every minute. None of this exists in the export.

Why token burn does not equal production readiness

Founders tell us they spent $800, $1,200, even $2,400 on Bolt.new credits before shipping. The token burn is real — Bolt.new's pricing is aggressive and the iteration loop eats context fast. But the spend correlates with visual polish, not production hardening. You can burn $2,000 making the dashboard look perfect and still ship an app where anyone can log in as anyone else.

This is the same pattern we documented in our audit of 50 vibe coded apps: the visual layer is over-optimized and the infrastructure layer does not exist. Bolt.new specifically amplifies this because the WebContainer hides the absence of real infrastructure behind a convincing simulation. Your app "runs" in the browser, so it must be ready. It is not.

The same gaps show up in Lovable deployments and in Cursor-built apps under traffic. Different tools, same missing layers — because all of them are optimized for the demo, not the deploy.

The 6-fix checklist, in order

If you are about to charge a customer, work this list top to bottom:

  1. Provision a managed Postgres and migrate every query off SQLite
  2. Add a migration framework and commit an initial migration from your current schema
  3. Rip out placeholder auth, install a real provider, and audit every protected route
  4. Add rate limiting and spend caps on every endpoint that costs you money
  5. Rotate all secrets, adopt a validated env loader, remove .env from the repo
  6. Install Sentry + structured logging + a branded 500 page + uptime monitoring

That is 2-3 weeks of focused work for someone who has done it before. It is 2-3 months of painful trial and error for a founder learning as they go — and the whole time, your first customers are hitting bugs you cannot diagnose.

This is the specific gap production engineering closes: take the working prototype and systematically install every missing production layer, without rewriting the product.

Frequently asked questions

Is it worth deploying Bolt.new to Netlify directly instead of exporting?

Netlify deploy from Bolt.new handles the static frontend fine but does not solve any of the six problems above. Your database still needs to move off SQLite, your auth is still placeholder, and Netlify Functions do not have built-in rate limiting. It saves one step (the initial deploy) and leaves the other twelve untouched.

Can I just ask Bolt.new to add rate limiting and real auth?

You can, and it will generate code that looks correct. The problem is consistency: Bolt.new will add rate limiting to the route you asked about and leave the other 15 routes unprotected. It will install Clerk in one component and leave the placeholder JWT import in the server middleware. We see this every audit — one fix applied, nineteen instances of the same problem left in place. Production engineering fixes every instance in one pass.

How much does it cost to take a Bolt.new app to production?

For a typical Bolt.new export with 15-25 routes and standard features (auth, payments, a dashboard, some AI calls), production hardening is a $15-30K engagement over 2-4 weeks. That is significantly less than rebuilding from scratch and roughly what founders spent on Bolt.new credits in the first place.

What about Bolt's "Deploy to production" button?

Bolt.new's production deploy still runs on StackBlitz's infrastructure with the same WebContainer limitations. It works for demos and early beta access. It does not work for charging money, handling support, or scaling past a few hundred users. The moment you have paying customers, you need real infrastructure.

Should I start over in Cursor or Next.js instead?

Rewriting loses the UI and product logic you already validated. The smarter move is keeping the Bolt.new export as the starting point and systematically hardening it. Most of the frontend code is salvageable. Most of the backend code gets replaced, but the API contract and data model stay the same. The typical ratio in our engagements: we keep 70% of the frontend, rewrite 60% of the backend, and finish in a quarter of the time a greenfield rebuild takes.

What breaks first when a Bolt.new app gets real traffic?

In order: auth (because the placeholder tokens have no expiration, sessions accumulate until the JWT verification queue backs up), then the database (SQLite on a container with no disk persistence), then the third-party API bill (no rate limits on the OpenAI proxy), then the error pages (stack traces leaking to users). We see this exact failure sequence on nearly every post-launch audit.

Do I need all six fixes or can I ship with some?

You need all six before a paying customer. Skipping rate limiting means one bad actor bankrupts you. Skipping real auth means your first data leak is a tweet-storm. Skipping migrations means you cannot ship an update without wiping data. These are not nice-to-haves — they are the difference between a product and a liability.

Your Bolt.new prototype is ready. The deployment is not.

The app you built is real. The UI works. The flows are validated. The only thing between you and your first paying customer is the infrastructure Bolt.new was never designed to build.

Book a free production audit for your Bolt.new app. We will map every gap between your export and a revenue-ready deployment, prioritize them by user impact, and fix the critical ones in the first week.

Your prototype cost you 2 million tokens. Your first customer is worth more than that.

Ready to ship your AI app to production?

We help funded startups turn vibe-coded prototypes into production systems. $10K-$50K engagements. Results in weeks, not months.

Get Your Free Audit