Skip to main content
Stackbastion

Draft, not yet published

Is code from Cursor production-ready? A checklist before you ship

7 July 2026· 5 min read · by Stackbastion

Cursor helped you build the thing in a fraction of the time, the code reads well, and the app runs. Now you’re about to put it in front of real users and a quiet voice is asking whether “it runs on my machine” and “it’s ready for production” are the same sentence. They’re not. Here’s what to actually check before you ship.

Why this happens with Cursor

Cursor is a genuinely good coding tool. It writes idiomatic code, follows the patterns in your repo, and rarely produces obvious garbage. That’s exactly what makes the gap sneaky. The code looks like a senior engineer wrote it, so you extend it the trust you’d extend a senior engineer, but the model optimized for “make this feature work,” not “make this survive contact with real users, real load, and real attackers.”

The result is code that’s correct for the happy path and silent on everything else. It doesn’t handle the empty state, the malformed input, the second concurrent request, or the case where the third-party API times out. None of that shows up in a demo. All of it shows up in production. Cursor also has no memory of your operational context: it doesn’t know what your backup strategy is, whether your keys are handled safely, or what your compliance requirements are, because those things aren’t in the file it’s editing.

So the code isn’t bad. It’s incomplete in the ways that only matter once real people use it.

The checklist

Run through this before you ship. It’s ordered roughly by how badly each item bites.

Security

  • No secrets in the frontend bundle. Fetch your built JS and grep it for key shapes. A service-role key or secret API key in client code is a full breach waiting to happen.
  • Every privileged call runs server-side, not from the browser.
  • Input is validated at the boundary, not trusted because “the form only sends valid data.” Anyone can bypass your form and hit the endpoint directly.
  • Auth checks are on the server, not just hidden UI. A hidden admin button isn’t access control if the endpoint still answers.

A fast first pass on the secrets item:

# Grep your production bundle for common secret shapes
curl -s https://your-app.example.com/assets/index.js \
  | grep -Eo "(sk_live_|service_role|AIza|AKIA)[A-Za-z0-9_-]+"

Nothing returned is the result you want. The full version of this check is in the 5-minute exposed-keys post.

Error handling

  • Every external call (database, third-party API, payment) has a failure path, not just a success path.
  • The app shows something sensible when a request fails, instead of a blank screen or a raw stack trace.
  • No catch block silently swallows an error. If it’s caught, it’s logged or surfaced.

Data and database

  • You have backups, and you’ve actually restored one. An untested backup is a rumor.
  • Queries that will grow have indexes. A where user_id = ... with no index is fine at 100 rows and a fire at 100,000.
  • Database connections are pooled, not opened per request. This is the number-one thing that falls over on launch day.
  • Migrations are real, versioned files, not manual dashboard edits you’ll never reproduce.

Operations

  • You have uptime monitoring, so you find out an endpoint is down before your users tell you.
  • You have logs you can actually search when something breaks at 2am.
  • Environment variables are set in every environment, not just the one where it happened to work.
  • There’s a staging environment, or at least a way to test a change before it hits users.

Load

  • You’ve thrown some concurrent traffic at it. Not a full load test, just enough to catch the connection-limit and N+1-query problems before Product Hunt does.

What Cursor is genuinely good at here

Worth saying plainly: Cursor is excellent for actually fixing these items once you know what they are. Hand it “add input validation to this endpoint with Zod” or “wrap this fetch in proper error handling and log failures” and it does clean work fast. The checklist isn’t a knock on the tool. It’s the list of things the tool won’t think to do unless you ask, because they live outside the file it’s looking at.

Or, we do it for you

Stackbastion supports Lovable and Git-repo imports directly today, but the production-readiness gap looks the same whatever built your app. If you want a second pair of eyes on your setup regardless of what you built it with, get a free production audit.

FAQ

Is Cursor code worse than code I’d write by hand?

Not really, and often it’s more consistent. The issue isn’t quality per line, it’s coverage: the model handles what you asked and stays quiet on the operational and security concerns you didn’t mention. A human engineer carries that context in their head. Cursor only sees the current file, so you have to bring the checklist yourself.

Can’t I just ask Cursor to make the code production-ready?

You can ask, and it’ll do a decent pass, but it’ll only address what’s visible in the code. It can’t test your backups, verify your database has connection pooling in production, or confirm your keys aren’t in the bundle, because those are facts about your deployment, not your source. Use it to fix each item, but you still have to run the checklist to know what to fix.

Which item on this list breaks apps most often on launch day?

Database connection limits. AI-generated backends love to open a fresh connection per request, which is invisible until a few dozen people show up at once and Postgres refuses new connections. Connection pooling with something like PgBouncer is the boring fix that keeps launch day from becoming an incident.