The short version
- Your application code is the portable part. Both platforms sync to GitHub as an ordinary repository; what you clone builds with ordinary tooling.
- The two platforms lock you in at different layers. Bolt outsources its hard parts to external services, so its dependencies are thin. Replit built its hard parts in-house — auth, database, storage, secrets, scheduled jobs all live inside the platform.
- You can classify your own app in an afternoon with a clean checkout and a handful of greps. Do that before you talk to anyone, including me.
- Order matters more than speed. Done in the right sequence, the app is never broken in the middle of the move.
- Staying is often correct. This page says so in its own section, on purpose.
What these tools actually hand you
Bolt.new is a StackBlitz product built on WebContainers — StackBlitz's runtime that runs Node.js inside the browser tab (webcontainers.io). That is why Bolt only supports JavaScript-based stacks: Node.js on the backend, browser-native frameworks on the front (Bolt docs). For data and users, a Bolt project uses either Bolt Database — the built-in hosted database with authentication management — or a connected Supabase project, which provides the hosted SQL database, auth and edge functions, and is available for Vite projects but not Next.js ones (Bolt Database docs, Supabase integration docs). Hosting is Bolt's own by default, with Netlify as the alternative (docs), and the GitHub integration commits your work automatically to a repository that lives outside Bolt (docs).
Replit Agent builds on a vertically integrated platform (Replit docs). By default it wires your app into Replit's own services: Replit Auth, where your users sign in by creating or using a Replit account — via Google, GitHub, X, Apple or email — and where the docs state plainly that the only way to implement it is through the Agent (docs); Replit Database, a fully managed PostgreSQL instance (docs); App Storage, object storage powered by Google Cloud Storage and accessed through Replit's JavaScript and Python SDKs (docs); workspace Secrets; and Replit's deployment types, including scheduled deployments for periodic work (docs).
This difference is the whole guide in one sentence: Bolt's lock-in is thin because it rents the hard parts from services you can hold your own account with; Replit's is thicker because it built the hard parts itself, and they do not exist outside Replit.
The portability line
What travels with you, on either platform:
- The front end. React or Vite components, routes, styling — a normal bundle that builds anywhere.
- Business logic written as plain TypeScript or JavaScript modules.
- The schema and the data. Replit Database is PostgreSQL; a Supabase database is PostgreSQL. SQL comes out of both.
- Server code — an Express app or edge functions are ordinary code, minus the wiring below.
What is platform-shaped, and has to be rebuilt rather than copied:
- Auth wiring. The sharpest case is Replit Auth: your users' identities are Replit accounts, and there is no standalone implementation to take with you (docs). Leaving means choosing a new identity provider and having every user sign in afresh — sessions and credentials do not export. On the Bolt side, Supabase Auth travels with a Supabase project you own, but callback URLs, redirect origins and email templates are all environment-shaped and need redoing for the new home. Bolt Database's built-in authentication is the same class of problem as Replit Auth: it exists inside the platform.
- Hosting and runtime assumptions. Code that has only ever run in a browser-tab dev container or a platform deployment slot carries assumptions — ports, process model, file paths, what happens on restart — that surface the first time it runs on a real host. None of them are hard to fix; all of them are invisible until you try.
- Secrets handling. Your keys live in a platform settings pane today.
The values move by hand in minutes; the real work is finding what leaked along the
way. In a Vite project, any environment variable prefixed
VITE_is compiled into the client bundle, and Vite's own documentation warns against putting anything sensitive there (Vite docs). A generator that needed an API call to work from the browser will happily have done exactly that. - Row Level Security posture, if Supabase is involved. RLS policies are the security model of a Supabase app — the client talks to the database directly, and the policies are what stand between users (Supabase docs). Generated policies need reading, not trusting; I cover this failure class in detail in the Lovable guide, and it applies unchanged here.
- Background jobs. On Replit, periodic work is a platform feature — scheduled deployments (docs) — that needs an equivalent on the new host. In a Bolt app there is often nowhere for real background work to run at all, so anything periodic tends to be faked in the client or simply absent. Either way this is built at the destination, not moved.
- File storage. Replit's App Storage is Google Cloud Storage behind Replit SDKs (docs) — the objects themselves can be copied out with standard tooling, but every read and write call site in your code changes. Supabase Storage travels with a Supabase project you own.
The afternoon test
You do not need anyone's opinion to find out which category your app is in. You need a clean machine and a few hours.
- Get the code out. Both platforms sync to GitHub; connect that if you have not, then clone the repository somewhere the platform has never touched.
- Try to build it.
npm install && npm run build. Every failure is a runtime assumption the platform was quietly satisfying for you. Write each one down — this list is the first half of your migration scope. - Grep for the platform's fingerprints. Each hit is a call site that changes:
# Replit service SDKs and config
grep -rn "@replit/" package.json src server
ls .replit replit.nix 2>/dev/null
grep -rn "REPLIT_" --exclude-dir=node_modules .
# secrets compiled into the client bundle
grep -rn "VITE_" src | grep -iE "key|secret|token"
# which external services are in play
grep -rn "supabase" package.json src
# schema as files, or only as live database state
ls supabase/migrations/ migrations/ 2>/dev/null
Then count. A handful of hits, a schema that exists as migration files, and a Supabase project you own: your app is mostly portable and the move is plumbing. Dozens of hits across auth, storage and jobs, a schema that exists only inside a live database, and identities that live with the platform: you are rebuilding a service layer, and you now know exactly which services. Both are workable positions — the point is that you found out from your own repository, in an afternoon, for nothing.
The failure classes these generators produce
These are the patterns worth checking for whether or not you ever migrate, because they are the ones that decide whether the app survives real users.
- Secrets in the client bundle. A generator asked to call a third-party
API takes the shortest path, and in a browser-first environment the shortest path
ships the key to every visitor. The
VITE_grep above finds the obvious cases (Vite docs); reading the network tab of the running app finds the rest. - Authorisation that exists only in the UI. The admin button is hidden from non-admins; the endpoint behind it checks nothing. Trace the two or three flows where this would hurt most — role assignment, anything touching money or other users' data — end to end.
- Permissive Row Level Security. A policy that is present but wrong —
USING (true)— passes every dashboard check and returns every row. Supabase's database advisors catch the crude cases; whether a policy is correct for your roles is a reading exercise nothing automates. - Schema as live state only. No migration files means no rollback, no reproducible environments, and a database whose true shape nobody can state. This gap costs nothing today and everything during an incident.
- The agent with production access. In July 2025, Replit's agent deleted a production database during an explicit code freeze — the incident, involving SaaStr's Jason Lemkin, was widely reported (Fortune). Replit responded by rolling out automatic separation between development and production databases and improving its rollback systems (Fast Company). The durable lesson is not about Replit: environment separation is something you verify, not assume — on any platform where an agent and your production data share a workspace. Note also that Bolt's version history does not restore database state (docs), so a code rollback is not a data rollback there either.
- Insecure defaults at scale. This is not one platform's carelessness. Veracode's 2025 study across 100+ models found AI-generated code chose the insecure implementation about 45% of the time, with no improvement in newer models (Veracode). Fast-built apps deserve review for the same reason fast-built houses deserve a survey.
What has to be rebuilt, platform by platform
Leaving Bolt
If your project runs on your own Supabase account, the largest cost of leaving does not exist: the database, auth and storage stay exactly where they are. What remains is hosting — a static Vite bundle any host can serve — plus moving secrets, updating auth callback URLs for the new domain, and the security pass above. If your project runs on Bolt Database, add a data-and-schema extraction first: the built-in database and its authentication live inside the platform (docs), and establishing which of these two situations you are in is the single most important fact in sizing the whole job. Anything periodic or queued gets built for the first time at the destination, because it had nowhere to run before.
Leaving Replit
Each platform service maps to a replacement, and the map is the scope:
- Replit Auth → your own identity provider. The one item with a user-facing cost: identities are Replit accounts, so users sign in afresh on the new system. Plan the mapping from old accounts to new — verified email is usually the join key — and plan the communication around it.
- Replit Database → your own PostgreSQL. It is managed Postgres underneath (docs), so schema and data come out with standard tooling via the connection string. Turn the schema into versioned migration files while you are at it — you are closing a gap, not just moving house.
- App Storage → your own bucket. The objects sit in Google Cloud Storage already (docs); copying them is mechanical. Rewriting every call site that used the Replit SDK is the actual work — your grep from the afternoon test already counted them.
- Secrets → the new host's secret store. Move each value by hand, and rotate each one as you go — a key that has lived in a shared workspace has had more readers than you think.
- Scheduled deployments → cron or a worker at the destination. Inventory them first; agents create these quietly and some will be dead.
The order that keeps you live
The principle: at every step, the app is whole on one side or the other. You can stop at any stage and still have a working product. Never take a step that breaks the old system before the new one has carried real traffic.
- Make the code build and pass its tests in plain CI first — before anything moves. This flushes out every runtime assumption while the platform is still happily serving production, and it costs production nothing.
- Stand up the replacements beside the originals. New database restored from a dump, new bucket with objects copied, new auth configured, jobs scheduled — all pointed at by a staging deployment, with production untouched.
- Move stateless things first. Frontend hosting can switch early and switch back in minutes. Stateful things — database, storage, auth — move last, once staging has proven the wiring.
- Treat the auth cutover as its own event. Where identities cannot migrate silently, users will sign in afresh; do it on its own day, with the old system still able to answer questions, not bundled into a weekend of everything else.
- Cut data over inside a freeze window, and keep the old platform alive but idle until the new one has survived enough real traffic that going back stops being a thought. Then decommission deliberately.
How to size it honestly
I have not found credible public data on what these migrations take, and I do not think it can exist in general form, because the answer swings on facts specific to your repository — which is why any figure produced before reading it is marketing, whoever says it. That includes me. This is a scoping question, not a fixed job, and the scope is the set of counts you produced in the afternoon test:
- platform SDK call sites (auth, storage, database clients), by file;
- auth touchpoints and whether identities can be joined to a new provider;
- scheduled jobs, live and dead;
- whether the schema exists as versioned migration files or only as live database state — the difference between portable and reconstruct;
- test coverage as measured, not assumed;
- secrets found by a history-wide scanner such as gitleaks or trufflehog, each one a rotation.
A real scope arrives with that arithmetic attached, so you can check it yourself. If someone hands you a number without the counts underneath it, ask for the counts.
When not to migrate
Migrating is not automatically the right answer, and a firm that opens with "you must get off the platform" is selling you their invoice. If you are still finding product-market fit, shipping daily through the agent, with few users and nothing regulated, the platform's speed is worth more than anything a migration buys — the right move is to fix the security posture where you stand and revisit when the facts change. A Bolt app on your own Supabase account may already be most of the way out without ever migrating at all.
The honest triggers are concrete: users you would have to apologise to for data loss; a restore obligation you cannot currently meet; compliance or procurement questions the platform cannot answer; background processing it cannot run; or a hired engineering team that needs CI, staging and rollback to do its job. If none of those are true yet, staying put is a fine outcome, and you probably do not need me. Whichever way it goes, write the decision down with the evidence that produced it — the record is worth more than the choice.
If you want help
What I do is the work described on this page, against your actual repository and services: classify each dependency as portable or platform-shaped, run the security pass policy by policy and flow by flow, and produce a migration scope with the counts it is derived from — so you can check the arithmetic rather than take my word for it. If the finding is that your app is fine where it is, that is what the report says. If that sounds useful, the enquiry form on the homepage is the way in.