Skip to content
All posts

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

DaveOTF Kit
9 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 plan from day one — and a kit can supply only the parts its delivered code contains. Our ship AI MVP to production checklist lays out that stack as one ordered path so nothing gets skipped.

"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.

One codebase. iOS, Android, and web.

The Fitness Kit is a mobile starter with its own API, with sign-in and a database. Live demo at fitness-preview.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
);

This is the standard migration discipline: database migrations are SQL statements that track schema changes over time, applied forward and rolled back safely. Migrate up, rollback down. Field-level control, audit trail, and production safety. And migrations are only half the data story — access control is the other half, which is why every production database needs our Supabase RLS production checklist applied before real user rows land in it.

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.

The SaaS Dashboard kit does not include product billing. Its customization guide documents an optional Stripe Checkout and webhook path, but the buyer must implement and test routes, event handling, receipts, plan rules, and audit behavior. The illustrative handler below is not shipped kit code:

// 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)
  }
})

The reason signature verification is non-negotiable: Stripe pushes real-time event data to your app as JSON payloads over HTTPS, and anyone can POST to an endpoint — only the signature proves the event came from Stripe. All payment flows run server–client–Stripe and back, not just a button that succeeds if you click. Async payment events (bank confirmations, disputes, subscription renewals) all arrive through this same background-job-shaped pipeline, so treat webhooks with the same retry and idempotency discipline.

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.

Deployment is kit-specific. Check the delivered README and configuration, then verify domain, TLS, environment, migration, and rollback steps with your hosting provider. Do not assume a universal OTF deploy command.

Use the repository's documented deployment path for the selected kit and hosting provider. Confirm exact commands and environment requirements before deploying.

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

Real binaries come from real build services — EAS Build is the hosted path for producing app binaries for Expo and React Native projects — not from wrapping a URL in a webview. 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.
  • Product billing is not included in SaaS Dashboard. Its customization guide documents an optional Checkout and webhook path; the buyer implements and tests payment state, failures, and access rules.
  • 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 what each kit actually delivers

Start from the current OTF kit catalog, then follow the README and setup guide inside the kit you select. The SaaS Dashboard kit provides authentication and a database foundation; product billing is not included. Its customization guide describes an optional Checkout and webhook path that you implement yourself. Verify supported platforms and deployment instructions in the chosen kit's own documentation.

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 kit you own can provide a useful foundation, but confirm its delivered features and limits before planning launch. SaaS Dashboard includes authentication and a database foundation; product billing is not included, and deployment and mobile capabilities depend on the selected kit. You can inspect and extend the code while planning the remaining implementation.

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

Sources

templatesbackendcross-platform
OTF Fitness Kit

Stop wiring. Start shipping.

  • Sign-in and a database wired in, with its own API
  • iOS + Android + web from one codebase
  • AI configs pre-tuned + 20+ task prompts per kit included
Free starter

Ship your first screen tonight — free starter in your inbox

The quickstart, the SDK repo and the live kit demos, on this screen and in your inbox.

No spam. Unsubscribe any time.

Get the free AI configs pack

The AI files every kit ships: CLAUDE.md, .cursorrules and task prompts. Drop them in and your AI tool knows your project.

No spam. Unsubscribe any time.

Prefer the free SDK? Star it on GitHub →