DEV Community

Alex Natskovich
Alex Natskovich

Posted on • Originally published at mev.com

Moving a Replit AI MVP to Production: What to Check First

A Replit MVP can get you to a working demo fast.

The risky part starts when users, payments, private data, and background jobs enter the picture.

Before you migrate to Vercel, AWS, Render, Railway, or Supabase, audit the app like an engineer who will be paged at 2 a.m.

1. Get the app out of the workspace

Start with code ownership.

git remote -v
git status
git log --oneline -5
Enter fullscreen mode Exit fullscreen mode

You want the source in a GitHub or GitLab repo owned by the company, not a shared Replit workspace or a freelancer account.
Add the boring files first:

.env.example
README.md
docker-compose.yml
.github/workflows/ci.yml
Enter fullscreen mode Exit fullscreen mode

Your .env.example should expose every required variable without leaking secrets:

DATABASE_URL=
SESSION_SECRET=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
OPENAI_API_KEY=
SENTRY_DSN=
APP_ENV=development
Enter fullscreen mode Exit fullscreen mode

If the app only runs because secrets live inside Replit, you do not have a deployable app yet.

2. Replace Replit assumptions

Replit is convenient because hosting, secrets, preview, and runtime sit in one place. Leaving it means finding every hidden dependency.

Common migration traps:

  • file uploads written to local disk
  • Replit DB or bundled SQLite used as production storage
  • hardcoded preview URLs
  • one database shared across dev and prod
  • no process manager for workers or cron jobs
  • no CI job before deploy
  • no rollback path

Search for platform-specific assumptions:

grep -R "replit" .
grep -R "localhost" .
grep -R "0.0.0.0" .
grep -R "process.env" ./src
Enter fullscreen mode Exit fullscreen mode

Also check whether the server binds to the platform port correctly:

const port = process.env.PORT || 3000;

app.listen(port, "0.0.0.0", () => {
  console.log(`Listening on ${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Tiny detail. Painful outage.

3. Split environments before touching features

Do this before adding another feature.

local -> local database
staging -> staging database
production -> production database
Enter fullscreen mode Exit fullscreen mode

A minimal CI gate is enough to start:

name: ci

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run lint
      - run: npm test
Enter fullscreen mode Exit fullscreen mode

Then add one smoke test around the path where money or data moves.

test("checkout requires an authenticated user", async ({ page }) => {
  await page.goto("/checkout");
  await expect(page).toHaveURL(/login/);
});
Enter fullscreen mode Exit fullscreen mode

Ouch if this fails. Good that it failed before launch.

4. Put auth and data rules under pressure

AI-generated apps often make login look complete while access control stays thin.

Check the API layer, not only the UI.

if (invoice.userId !== session.user.id) {
  return res.status(403).json({ error: "Forbidden" });
}

Enter fullscreen mode Exit fullscreen mode

Then test it directly:

curl -H "Authorization: Bearer USER_A_TOKEN" \
  https://api.example.com/invoices/USER_B_INVOICE_ID

Enter fullscreen mode Exit fullscreen mode

Expected result: 403.

If you get 200, pause the migration and fix authorization first.

5. Add logs before users find the bugs

At minimum:

import * as Sentry from "@sentry/node";

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.APP_ENV,
});

Enter fullscreen mode Exit fullscreen mode

Track auth failures, payment webhooks, failed AI calls, and slow database queries.

For AI features, add cost controls early:

if (user.monthlyTokensUsed > user.monthlyTokenLimit) {
  throw new Error("AI usage limit reached");
}
Enter fullscreen mode Exit fullscreen mode

No one wants to discover runaway token usage from the invoice.

6. Vendor options, ordered by technical fit

If you need outside help, choose based on the stack and failure mode.

MEV

Good fit when the app handles payments, health data, regulated workflows, or complex integrations. MEV is worth considering when you need an audit, migration plan, and production engineering rather than a quick patch.

WAYF Digital

Good fit when the app already uses Supabase and Next.js. Useful for fixing row-level security, auth policies, and backend structure without changing the foundation.

Slashdev.io

Good fit when you need senior engineers comfortable with Claude Code and agentic workflows. Better for fast hardening than broad product ownership.

Red Leg Dev

Good fit for a focused rescue where one senior engineer can inspect the app and fix the highest-risk paths.

Pragmatic Coders

Good fit for funded products that need a larger team across product, design, DevOps, and engineering.

Handoff checklist

Do not close the migration until you have:

  • company-owned repo
  • documented env setup
  • staging and production split
  • database migration process
  • payment webhook docs
  • monitoring access
  • rollback instructions
  • credentials moved to company-owned accounts

A deployed app without those pieces is fragile.

Start with the source, the secrets, the database, and the deploy path. Features can wait.

Full vendor breakdown: https://mev.com/blog/best-agencies-for-turning-your-vibe-coded-app-into-a-production-ready-product

Top comments (0)