Skip to content
OTFotf
All posts

Why sandbox MVPs break in production and what full-stack kits fix

D
DaveAuthor
7 min read
Why sandbox MVPs break in production and what full-stack kits fix

A sandbox MVP is easy to ship — and just as easy to break. Stack an expo starter, drop a mock auth widget, paste in a fake DB, throw a Stripe button on top. Greenfield dev is fast when nothing has to really work. But the moment you push for production — user signups, real billing, mobile app store builds, a custom domain, all with a single, shared codebase — the seams split. "Production-ready" is a concrete checklist, not a feeling. Here’s how shipping for real is different, where MVPs fail, and what owning a full-stack kit really fixes.

MVP shortcuts work — until they don’t

In the build-for-demo stage, you optimize for speed. You skip or mock every slow part:

  • Auth: "Sign in with Google" via a free widget with no user DB and no email change support.
  • DB: Local SQLite, no migrations, no production isolation, zero backup.
  • Billing: Stripe test mode, no real hooks, no audit or invoices.
  • Deploy: Hosted-in-editor or "preview" platforms with no domain or real TLS.
  • Mobile: PWA shell, maybe, never a real iOS/Android binary.

This ships the deck. But not a product. Try to take payments, onboard an actual user, build for mobile, or wire up a real domain, and each piece breaks. Worse: these hacks won’t upgrade. You have to throw them out and rewrite — often as a rush job, hacking in bits of a “real app” after you promised the demo could go live.

Takeaway: The tools that get you to demo are not the tools you want in prod, and you won’t paper over the gap with config or wrappers. You need a production stack from day one — or a kit that wires you straight to it.

“Production-ready” means more than avoidance of failure

People chase “prod-ready” as a platitude, like “swappable” or “scalable,” but it has an explicit list:

  • Real user accounts, with changing emails and passwords backed by a database you own
  • Database migrations, so you can upgrade your schema without dropping user data
  • Real payments, wired live, with receipt/invoice/chargeback flow
  • Auditable deploy, to a real domain, on infra you can introspect and own
  • Mobile app binaries, signed and uploaded, not a PWA-in-a-webview
  • A CI/CD path that can rebuild, test, and deploy — not just “run dev on my laptop”

An MVP that mocks or handwaves any one of these “just until later” will break bumpily when taken to production. The cost is not just time: it’s trust, support, and a rewritten codebase at the worst moment.

11 production screens. Auth, DB, Stripe — all wired.

The SaaS Dashboard Kit ships everything already connected. No Vercel config, no Supabase account. Live demo at saas.otf-kit.dev.

See the live demo

Auth: a real user system is not “Sign in with Google”

Sandbox MVPs pick auth by whatever’s fastest to demo, not what fits real user needs. The common pattern:

// Auth in a sandbox MVP
import { GoogleAuthProvider, signInWithPopup } from 'fake-fire-auth'
signInWithPopup(new GoogleAuthProvider())

No password login. No email change. No database consistency. No Stripe integration. The "user" exists — but nowhere you can query, reset, or control.

Stack in OTF’s SaaS kit:

// Shipping auth: real accounts, reset flows, database-backed
await signupWithEmail({ email, password })
await signinWithEmail({ email, password })
await changeEmail(userId, newEmail)

Everything flows through a user table, supports password resets, change flows, and connects to the rest of your stack. You own the users and the lifecycle — not some third-party widget.

Takeaway: Demo auth is a spectrum toy. Production auth means accounts, lifecycle, revocation, and audit.

The DB: why “local only” costs you twice

Nothing in a sandbox database survives real users. Schemaless or prototype DB layers break down on the first migration or multi-user race. Here’s a typical MVP setup:

// Fake, local, in-memory DB
const db = []
function createUser(user) { db.push(user) }

Take that to prod: No migration path, no backup, no persistent store, no isolation — no “pull this to staging.”

OTF kits wire in a real, relational store with migrations, not “YAML as database.” Schema changes are code:

-- OTF kit ships with forward/back migrations
CREATE TABLE users (
  id UUID PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  password_hash TEXT NOT NULL
);

Migrate up, rollback down. Field-level control, audit trail, and production safety.

Takeaway: Run your app on a production-grade database from the first commit, or be ready to rewrite everything that touches data.

Payments: a “Stripe button” isn’t a billing system

Test-mode-only Stripe widgets don’t handle receipts, failed invoices, or real webhook security. Here’s the MVP pattern:

// Button on the frontend, nothing else
<StripeCheckoutButton amount={999} />
// No server, no hooks, no audit

This clears a test payment. It doesn’t prove product/plan/purchase flows, failed payments, invoice delivery, or actual subscription logic.

OTF’s SaaS Kit wires Stripe from the backend to the UI, with receipts, live hooks, per-plan logic, and audit baked in:

// Server-side: handle events
app.post("/stripe/webhook", verifyStripeSignature, async (req, res) => {
  if (req.body.type === "invoice.payment_succeeded") {
    await markSubscriptionPaid(req.body.data.object.customer)
  }
})

All payment flows run server–client–Stripe and back, not just a button that succeeds if you click.

Takeaway: You ship a business, not just a UI. Payment is flows, errors, audit, and state change — not a “checkout” component.

Deploy: shipping to prod is not “share this URL”

A demo works on localhost and a test URL. Production means:

  • A custom domain (not app.demo.pseudoplatform.io)
  • TLS (real HTTPS, valid cert, ideally managed)
  • Upgrading without downtime
  • Audited deploys and logs

Copy-paste deploys from sandbox platforms do none of these.

OTF kits ship one-script deploy. You wire a domain, generate a deploy script, ship with TLS and DNS all in one step. There’s no “now copy these settings over by hand,” no uninspected black boxes, no “hope this is secure.”

# OTF deploys everything in one pass
otf deploy --domain=yourapp.com --tls --db-migrate

Takeaway: Real production is an owned domain and a pipeline that you can repeat, not just a demo preview link.

Mobile: a real app isn’t a PWA in a webview

Cross-platform means "it runs the same everywhere," not "some features degrade gracefully." Sandboxed MVPs throw up a PWA or webview wrapper and call it shipped. But distribution, push, and monetization all fail:

  • No app store listing
  • No native push
  • No in-app purchase
  • No offline-first guarantee

OTF Fitness ships as real iOS/Android builds, from a codebase that actually runs natively. Here’s the gap:

Ship TargetMVP PWAOTF Fitness kit
App Store binary
Push notifications
One codebase logic~
Offline support

The same component renders and behaves identically everywhere — no wrappers, no fallback rendering. “Build once, ship real apps.”

Takeaway: You don’t support mobile users if you’re shipping a webview. Build binaries or expect your app’s best features to break for half your users.

What a full-stack, owned kit actually closes

Owning the kit closes the gap the demo blasts open:

  • You have real user state, testable and auditable, with upgradable flows and data you own.
  • Payments work end to end, handle failure and audit, and are wired to your user’s lifecycle, not pasted in.
  • Deploys are repeatable and predictable — you ship a real app with a custom domain, on infra you can inspect.
  • Mobile is not an afterthought — binaries exist from day one, not as a failed stretch goal.

And you get all that without spending the first month burning the MVP scaffolding and hoping critical paths don’t break.

See it: SaaS and Fitness, already wired and shippable

Go pull the real thing:

npx otf-kit@latest new saas-dashboard
# or, for mobile:
npx otf-kit@latest new fitness

Web demo ships styled, full-stack, auth + billing + real DB, and is plug-in ready for a custom domain:

otf deploy --domain=your-saas.com

Fitness kit: Build and ship iOS, Android, and web from the same codebase. Functions like <WorkoutCard /> and <LoginForm /> ship visually identical on all three platforms.

scene

Every kit is tested against an AI agent with 20+ real prompts (CLAUDE.md, .cursorrules) so a coding tool extends the app’s core logic instead of blindly rewriting boilerplate.

Owning prod is the difference between launch and vapor

A sandbox starter gets you a demo. A full-stack kit you own, scoped for production, is what lets you actually onboard users, bill, and ship everywhere. The difference is not "polish" or "extra config" — it's a foundation you don't have to throw away the second real usage arrives. OTF shorthands the pain by shipping the full list — real auth, real DB, payments, deploy, and mobile — in a codebase you actually own and can ship.

Stop rewriting the demo. Start with a codebase that works in production, out of the box.

backendkitsannouncement
OTF SaaS Dashboard Kit

Ship the product, not the setup.

  • 11 production screens — auth, billing, team, analytics, settings
  • Real Postgres + Stripe + Better Auth, all wired on day 1
  • CLAUDE.md pre-tuned so your agent extends instead of regenerates