MVP software development when the prototype already exists: finishing what Cursor started

A field guide for taking a half-built Cursor or v0 prototype across the line. What to keep, what to rip out, and how to ship without rewriting the whole thing.

MVP software development when the prototype already exists: finishing what Cursor started
KEY TAKEAWAYS
  • A Cursor prototype is a spec written in code, not a foundation. Treat it like a Figma file you can run.
  • Don't rewrite. Triage: keep the UI, replace the data layer, harden auth, billing, and email before anything else.
  • The 'last 20%' is auth, payments, error states, deploys, and abuse protection. Budget two to four weeks for it.
  • Pick boring infra on purpose: Hetzner or Cloudflare Workers, Stripe, Resend, Turnstile. Save novelty for the product.

Most of the projects that land in our inbox arrive the same way. A founder opens a GitHub repo, says “it mostly works,” and then admits they’ve been stuck for six weeks trying to add login. The prototype runs on localhost. It looks great. It cannot take a payment, cannot send an email, and falls over the moment two people use it at once.

This is the new shape of MVP software development. The prototype already exists. Someone built it in a weekend with Cursor or v0, got 80% of the way there, and then hit the wall where vibes stop working and engineering starts.

This post is about getting across that wall.

What you actually have when you have a Cursor prototype

You have a spec. That’s it. A spec written in TypeScript instead of Notion.

This is more valuable than people give it credit for. A working prototype answers questions a PRD never can: what the empty state looks like, how the form behaves when you tab through it, whether the dashboard layout survives a long company name. Cursor and Claude Code are very good at producing this. They are less good at producing something you can put a credit card into.

So before you touch the code, do a triage pass. Open the repo and ask four questions:

  1. Does the UI represent what we actually want to ship? If no, fix that in Cursor before you do anything else. It’s still cheaper there.
  2. Where does data live, and is it real? Half of these prototypes have hardcoded JSON pretending to be a database.
  3. Is there any auth at all, or is every route public?
  4. What’s the deploy story? Vercel free tier with no environment variables counts as no deploy story.

Write the answers down. That’s your scope.

What to keep, what to rip out

Keep the UI. Almost always. The components, the Tailwind classes, the page structure, the copy. If a designer or the founder spent real time on it in v0, it’s probably fine. Ripping it out to “clean it up” is how two-week projects become two-month projects.

Rip out anything that touches data. Not because the AI wrote it badly, but because it wrote it assuming a toy scenario. The typical pattern: a lib/db.ts with an in-memory array, or a Supabase client wired to a project whose anon key is committed to the repo. Replace it with something real. We usually go Postgres on Hetzner with Drizzle, or D1 if the whole thing fits on Cloudflare Workers.

Rip out the auth. There is no scenario where the auth a prototype shipped with is the auth you want in production. Use Clerk, Auth.js, or Lucia. Pick one in ten minutes and move on.

// What the prototype has
export async function getUser() {
  return { id: "1", email: "test@test.com", plan: "pro" }
}

// What you need
import { auth } from "@/lib/auth"
export async function getUser() {
  const session = await auth()
  if (!session) throw new UnauthorizedError()
  return session.user
}

That function gets called from forty places. Fixing it once unblocks the whole app.

The last 20% is 80% of the work

This is the part founders underestimate. The prototype shows the happy path. Real MVP web development is the unhappy paths.

Here’s the list I run through on every finish-the-prototype engagement. It’s boring on purpose.

None of this is glamorous. None of it is what Cursor is good at. All of it has to exist before you can charge money.

Budget two to four weeks for this phase, depending on how much the prototype got right. If someone tells you they can do it in three days, they’re going to ship something that breaks the first week.

A real example

Last spring a founder came to us with a Next.js app a contractor had built in Cursor. Lead capture tool for real estate agents. The UI was honestly good. The lead form posted to a route handler that wrote to a JSON file. There was a “login” button that did nothing.

We kept maybe 90% of the frontend. Replaced the JSON file with Postgres and Drizzle. Added Auth.js with magic links through Resend. Wired up Stripe with two plans, a trial, and a webhook that updates the user’s plan in the database. Put Turnstile on the public lead form because of course someone was already spamming it. Deployed to a single Hetzner box behind Cloudflare.

Elapsed time: 17 days. The contractor had been at it for two months.

The lesson isn’t that the contractor was bad. The prototype was good. The lesson is that finishing is a different job than starting, and it takes a different kind of attention.

When to throw it away

Sometimes you should. Signs the prototype isn’t worth saving:

In those cases, keep the design and the copy, throw out the code, and rebuild. It’s faster than untangling.

Where this leaves us

The interesting thing about the current moment is that the prototype-to-production gap got wider, not narrower. AI tools made the first 80% almost free. The last 20% is the same work it always was: auth, billing, email, deploys, error handling, and the dozen small things that make software feel finished.

If you’ve got a half-built thing on your laptop and you’re tired of looking at it, send it over. I’ll tell you honestly whether to finish it or start over.

FREQUENTLY ASKED

Common questions

What does MVP software development actually mean in 2025?

It used to mean building the smallest version of a product that proves the idea. Now it usually means finishing a prototype that already exists. The work has shifted from writing the initial code to making that code production-ready: real auth, payments, email, monitoring, and a deploy that doesn't fall over. The scope is smaller, but the bar for what counts as "shipped" is higher because users expect Stripe-quality polish.

Should I rewrite my Cursor prototype or build on top of it?

Build on top of it if the UI is decent and the data model isn't deeply broken. Rewrite if the AI generated three different state patterns, the schema doesn't match the feature set, or the prototype is in a framework that won't scale (Streamlit, Gradio, raw Flask with no structure). The default should be to keep the frontend and replace the data, auth, and infrastructure layers.

How long does it take to take a prototype to production?

Two to four weeks for most projects we see, assuming the prototype is in a reasonable framework like Next.js or SvelteKit and the founder knows what features are in scope. The variability is mostly about scope creep and how much the prototype got wrong on data modeling. If someone quotes you three days, they're skipping things like rate limiting, error monitoring, or proper webhook handling.

What does a custom MVP development engagement cost?

For a finish-the-prototype project: usually between $8k and $25k CAD depending on scope. The variables are payment complexity (one plan vs. usage-based billing), whether there's a mobile app involved, and how much of the prototype survives the triage pass. We quote a fixed price after a paid discovery call where we actually open the repo.

Can I just keep using Cursor or Claude Code to finish it myself?

Sometimes, yes. If you're technical enough to read the code and you have time, the AI will get you further than people think. Where it tends to fail is the integration work: Stripe webhooks that handle every edge case, auth flows that survive password resets across devices, deploy pipelines that don't leak secrets. These need someone who's done it before, because the AI will confidently produce code that looks right and breaks under real traffic.

Do you work with founders outside Canada?

Yes. We're based in Canada but most of our clients are in the US and EU. Async-first, with a weekly call. Time zones haven't been an issue. See the [agents page](https://edsdev.ca/agents) if you're also looking at adding AI features to the product itself.

Related posts