Taking a Lovable, Bolt or Replit App to Production

Taking a Lovable, Bolt or Replit App to Production

Author
Daniel Botha
Daniel Botha
Writer at Fly.io
Published

Taking a Lovable, Bolt or Replit app to production means getting its generated code into a Git repository you control, deploying the stack the builder actually produced on a host that runs it as-is, and moving secrets and the database onto accounts you own.

The prototype works. It has users, or it is about to, and the builder’s one-click publish was fine for the demo. Now a customer wants a custom domain, a second developer wants pull requests, the bill is tied to an editor subscription, and nobody is sure where the Supabase service key lives.

The export is quick. What breaks is around it: a single-page app that returns 404 on deep links, a server on a port the new host never routes to, and a database an ocean away from the app that queries it.


Can Lovable, Bolt and Replit Apps Be Production-Ready?

Yes. The code these builders generate is ordinary React, Next.js or Node, and it runs in production the same way hand-written code does. What makes a prototype unready is the surrounding decisions: who owns the backend, whether Row Level Security is on for every table, where secrets live, and whether anyone can review a change before it ships.

Leaving Lovable’s hosting means it “no longer manages your development and deployment workflow”, and you take on the infrastructure, certificates and scaling, plus the AI provider accounts, credentials, billing and rate limits that its built-in features handled.[1] Replit warns that the file system in a published app “is not persistent and resets every time you publish”, so anything written to local disk was already disposable.[2]

The work before production is therefore an audit, not a rewrite. Confirm what stack was generated, take ownership of the database, move every key out of the code, and put the repository behind a review process.


What Stack Did Lovable, Bolt or Replit Generate?

The three builders produce different things, and each deploys differently.

  • Lovable has generated two shapes. Older projects are React with Vite, which “build to static files that any static host can serve”. Newer projects use TanStack Start, which runs server code (server-side rendering, server functions and API routes) and needs a host that runs a server process as well as serving files.[1] A vite.config.ts with no server entry is the first kind; a TanStack Start dependency in package.json is the second.
  • Bolt supports any JavaScript frontend framework with a Node.js backend, and only JavaScript backends: PHP and Python are not supported.[3]
  • Replit runs most languages, and its Agent can wire in a managed PostgreSQL database and App Storage backed by Google Cloud Storage.[4]

That gives three stacks to plan for: a static Vite build, a Next.js or TanStack Start server, and a Node API such as Express.


How Do I Export the Code to GitHub?

Connect the builder to GitHub and let it push; avoid the ZIP download where a sync exists, because a sync keeps the editor and the repository in step.

Lovable syncs with GitHub, GitLab or Bitbucket on every plan, while downloading the codebase as a .zip requires a paid plan.[1] The sync runs both ways, but “Lovable only edits and syncs one branch at a time”, the default branch unless you switch it.[5] Neither the sync nor the download carries data: the database and storage files are exported separately.[1]

Bolt connects through its GitHub app. It commits each change that does not break the project and checks GitHub every 30 seconds for commits made elsewhere. If both sides change at nearly the same moment, Bolt keeps its own version and overwrites GitHub’s.[6]

Replit uses a Git pane that connects a repository to a provider and pushes in one click, or a remote added from the Shell. GitHub authentication uses a personal access token rather than a password.[7]


Which Generated Apps Deploy Unmodified, and Which Need a Dockerfile Change?

Server apps generally deploy unmodified; the static single-page app and any server with a hard-coded port need a small change. Run fly launch in the repository root and it detects the framework, writes a Dockerfile and a fly.toml, and deploys.

Generated stack Typical source Deploys unmodified? Change needed
Next.js Bolt Yes Optional: output: 'standalone' for a smaller image; NEXT_PUBLIC_ values as build args
TanStack Start Newer Lovable Yes, if package.json has a start script Add the start script if missing
Vite and React single-page app Older Lovable, Bolt No Serve dist/ through nginx with an index.html fallback
Express or Node API Replit, Bolt Yes, if the port matches Set internal_port to the port the server listens on

Sources: [1][3][8][9]. Checked 2026-10-12.

Next.js and TanStack Start

These are Node servers and deploy as they are. For Next.js, output: 'standalone' makes the build emit a minimal server.js with only the files it needs, so the image skips most of node_modules; the generated Dockerfile is adjusted for it when the setting is present.[9] The Next.js guide covers the build arguments. TanStack Start needs only a start script, which the Dockerfile generator expects any server app to have.

The Vite single-page app

A Vite build is a folder of static files with no server to start, so the final stage of the generated Dockerfile, which runs the app with Node, gets replaced with nginx:

-FROM base
-COPY --from=build /app /app
-EXPOSE 3000
-CMD [ "npm", "run", "start" ]
+FROM nginx:alpine
+COPY --from=build /app/dist /usr/share/nginx/html
+COPY nginx.conf /etc/nginx/conf.d/default.conf
+EXPOSE 80

The nginx.conf holds the line every client-routed app needs, so that /dashboard loaded directly returns the app instead of a 404:

server {
  listen 80;
  root /usr/share/nginx/html;
  location / { try_files $uri /index.html; }
}

Then set internal_port = 80 under [http_service] in fly.toml. One more trap: VITE_ variables are “statically replaced at build time”, so they have to exist during the build, not only at runtime.[8] Pass them under [build.args] in fly.toml and declare them with ARG in the build stage.

The Express or Node API

Replit’s publishing already requires a server to listen on 0.0.0.0, because “listening only on localhost or 127.0.0.1 does not work for published apps”.[2] So a Replit server usually binds correctly already. What differs is the port. If the code hard-codes one, match it in fly.toml rather than editing the app:

 [http_service]
-  internal_port = 3000
+  internal_port = 5000

Replit’s managed database and App Storage stay behind on Replit, so their connection details are replaced with your own Postgres and object storage before the move. This is the same pattern any Node.js hosting choice runs into.


How Do I Connect My Own Supabase Project in Production?

Create or keep a Supabase project you own, put the browser-safe key in the build and the secret key in runtime secrets, and run the app in the region nearest the database.

Moving off the builder’s backend

Lovable Cloud’s backend can move to managed Supabase or self-hosted Supabase. Moving only the PostgreSQL database “does not move authentication, storage, realtime, or Edge Functions”, so plan each of those explicitly.[1] Bolt offers its own Bolt Cloud database or a Supabase connection.[3]

Which key goes where

Supabase’s publishable key (the legacy anon key) is “safe to expose online” because it only reaches what Row Level Security allows. The secret key (legacy service_role) “bypasses every Row Level Security policy” and must never reach a browser or source control.[10] The project URL and publishable key go in as build args, since the frontend bundles them. The secret key and any direct DATABASE_URL go in as runtime secrets:

fly secrets set SUPABASE_SECRET_KEY=... DATABASE_URL=...

Before launch, turn on RLS for every table. A table without it is readable by anyone holding the publishable key, and that key is in your JavaScript bundle.

Connection mode and region

For a persistent server, Supabase recommends a direct connection on port 5432 where the network supports IPv6 or the IPv4 add-on is enabled, and the session pooler, also on 5432, otherwise. Transaction mode on port 6543 is meant for serverless functions.[11] Each Supabase project lives in one AWS region, for example us-east-1 in North Virginia or eu-central-1 in Frankfurt.[12] Every server-side query crosses the distance between the app and that region, so set the app’s primary_region to the matching location: iad (Ashburn, Virginia) for us-east-1, fra for Frankfurt, lhr for London, sin for Singapore. For a broader view of the database side, see Postgres hosting options.


How Do I Get Preview Deploys and a Staging Environment?

Deploy every pull request to its own temporary app, and keep the builder synced to a single branch so previews never fight the editor.

Per-PR preview deploys are what teams expect to lose when leaving a frontend platform; the Fly.io and Vercel comparison covers that trade. Fly.io’s review apps guide uses the superfly/fly-pr-review-apps GitHub Action: on each opened, reopened or updated pull request it deploys the branch to pr-<number>-<owner>-<repo>.fly.dev, and it runs again when the PR closes. For the full flow, with an isolated app and database for every pull request and a coding agent reading the preview back, see per-PR preview environments for coding agents.

The builder’s sync model shapes the workflow. Lovable edits one branch at a time, so pull requests opened from other branches do not appear in the editor until they are merged into the synced branch.[5] That works in your favour: the editor writes to main, humans and agents work on branches, and each branch gets a preview. Bolt’s 30-second sync and its overwrite rule mean nobody should push to the branch Bolt is editing while a Bolt session is open.[6]

For staging, point previews at a second Supabase project rather than production. A preview app built against the production secret key can change real data.


Lovable, Bolt and Replit Apps on Fly.io

Fly.io runs the exported repository as it stands. fly launch reads the project, recognises Next.js, a Node server or a TanStack Start app, writes the Dockerfile and fly.toml, and deploys to a Fly Machine: a hardware-isolated microVM running your server process. The Vite single-page app is the one stack that needs the nginx stage above, and the change is the four lines shown.

Secrets set with fly secrets set are encrypted in a vault and appear as environment variables on every Machine in the app, so the Supabase secret key never sits in the repository. primary_region pins Machines next to the Supabase project. Fly Proxy can stop Machines when traffic goes quiet and start them on the next request, which keeps a low-traffic launch inexpensive on per-second pricing; the Fly.io calculator prices a configuration before you deploy it. Review apps give every pull request its own URL, and the same Machines later run background workers alongside the web process.


Frequently Asked Questions

How do I publish my Lovable app?

Lovable publishes a project to its own hosting from the editor, which suits a prototype or a demo. For production on infrastructure you control, sync the project to GitHub, then run fly launch in the repository so Fly.io detects the stack, writes a Dockerfile and deploys it.

What happens to my app if I stop paying for Lovable?

The code stays yours, because Git sync works on every plan and the repository lives in your own GitHub account. Hosting, the built-in backend and Lovable’s AI features stop being managed for you, so the app needs a new host such as Fly.io, a Supabase project you own and your own AI provider keys.

How much does it cost to host a Lovable or Replit app outside the builder?

It depends on the app’s size and traffic rather than on the builder that generated it. On Fly.io you pay per second for the Machines you run, Machines can stop when traffic is idle, and the Fly.io calculator prices a configuration before you deploy. A Supabase plan is billed separately by Supabase.

Can I keep editing in Lovable or Bolt after I deploy somewhere else?

Yes. Both sync with GitHub in both directions, so edits made in the builder land in the repository and Fly.io deploys them like any other commit. Lovable syncs one branch at a time, and Bolt overwrites GitHub if both sides change at once, so keep the builder on its own branch.

Does Lovable’s built-in AI work after I move the app?

No, not once the app has fully left Lovable. AI features run through Lovable only while the app uses its services, so a moved app calls an AI provider directly with its own API key. On Fly.io that key goes in with fly secrets set and reaches the server as an environment variable, never the browser.

Can I move a Replit app to another host?

Yes. Push the code to GitHub from Replit’s Git pane, replace Replit’s managed database and App Storage with your own Postgres and object storage, and run fly launch so Fly.io deploys it. Replit servers already listen on 0.0.0.0, so usually only the port in fly.toml needs to match.

Do I need to rewrite a vibe-coded app before production?

No. Generated React, Next.js and Node code runs in production like hand-written code, and Fly.io deploys it as exported. The work is an audit: enable Row Level Security on every table, move secret keys out of the code, own the database and put changes through review.

What region should my app run in if I use Supabase?

The one closest to the Supabase project’s AWS region, because every server-side query travels between the two. On Fly.io, set primary_region in fly.toml to match: iad for us-east-1 in North Virginia, fra for Frankfurt, lhr for London and sin for Singapore.


Sources

  1. ^ Lovable, “Deployment, hosting, and ownership options with Lovable”. docs.lovable.dev/tips-tricks/deployment-hosting-ownership. Checked 2026-10-12.
  2. ^ Replit, “Troubleshoot publishing”. docs.replit.com/build/troubleshooting. Checked 2026-10-12.
  3. ^ Bolt, “Supported technologies”. support.bolt.new/concepts/supported-technologies. Checked 2026-10-12.
  4. ^ Replit, “Storage and Databases”. docs.replit.com/learn/projects-and-artifacts/storage-and-databases. Checked 2026-10-12.
  5. ^ Lovable, “Sync your Lovable project with GitHub”. docs.lovable.dev/integrations/github. Checked 2026-10-12.
  6. ^ Bolt, “GitHub for version control”. support.bolt.new/integrations/git. Checked 2026-10-12.
  7. ^ Replit, “Using the Git pane”. docs.replit.com/replit-workspace/workspace-features/git-interface. Checked 2026-10-12.
  8. ^ Vite, “Env Variables and Modes”. vite.dev/guide/env-and-mode. Checked 2026-10-12.
  9. ^ Next.js, “output”. nextjs.org/docs/app/api-reference/config/next-config-js/output. Checked 2026-10-12.
  10. ^ Supabase, “API keys”. supabase.com/docs/guides/api/api-keys. Checked 2026-10-12.
  11. ^ Supabase, “Connect to your database”. supabase.com/docs/guides/database/connecting-to-postgres. Checked 2026-10-12.
  12. ^ Supabase, “Available regions”. supabase.com/docs/guides/platform/regions. Checked 2026-10-12.

Deploy your exported app

Run fly launch in your exported repo and get a deployed app with secrets configured.

Sign up