When to stay on Bubble and when to migrate
Do not migrate just because the Bubble app is annoying
Most Bubble apps do not need to migrate to code.
The usual problem is that the app is badly built: unclear data types, repeated workflows, missing privacy rules, searches in the wrong place, reusable elements doing too much, and logic scattered across pages. If you rebuild that in Next.js and Supabase, you still have a badly built app. It just has a different stack.
I would only treat migration as the answer once you know the problem is Bubble itself, not the way the Bubble app was built.
For example, if every change is painful because a page has twenty workflows that all update the same Order, fix that first. Move the shared logic into backend workflows or custom events. Clean up the Order fields. Apply privacy rules properly. Make the important searches obvious. That might solve the actual problem without spending months replacing the app.
Migration is not screen rebuilding
Migration is not screen rebuilding.
Rebuilding the screens is usually the easy bit. The work that breaks migrations is normally:
Mapping Bubble data types to the new database
Migrating existing Things safely
Preserving privacy and permission behaviour
Rebuilding backend workflows and scheduled workflows
Replacing plugin behaviour
Handling old edge cases that users still rely on
Testing the new app against real customer flows
Deciding when Bubble and the new app are allowed to write data
Planning the cutover
This is why quick migration promises are usually suspicious. A nice product page in Next.js does not prove the migration works. A Supabase table that looks like the Bubble data type does not prove the data can be moved safely.
Take a marketplace app. The product page is not the hard part. The hard part is Orders, Payments, Sellers, Reviews, Disputes, Messages, refunds, admin views, payout state, privacy rules, and users who are halfway through something when you cut over.
If you are migrating, test the data migration as you build each module. Do not leave it until the end. If the old Bubble data cannot be transformed into the new schema, you want to know that before the new app depends on that schema everywhere.
Do not copy Bubble technical debt into code
A migration is one of the few chances you get to redesign the app around what the product has become.
Do not copy the Bubble database table-for-table into Supabase unless that structure is actually good. Do not copy every Bubble workflow into an API route unless that workflow still makes sense. Do not assume every field is still used because it exists in Bubble.
The Bubble app is evidence, but it is only a starting point.
Some parts should be copied. If a backend workflow already models a clear business action, rebuild that action properly in code. Some parts should be deleted. Some parts should be redesigned because the Bubble implementation was a workaround from three years ago.
AI coding tools make this easier to get wrong. Claude Code, Cursor, v0, and similar tools can generate components, API routes, database tables, and tests quickly. They can also confidently reproduce the same bad structure if you give them the Bubble app and ask them to rebuild it.
Use AI tools to help implement the plan. Do not use them to avoid understanding the current app.
External databases from day one usually mean Bubble is wrong
If a new app needs an external database from day one, Bubble is probably the wrong platform for that app.
Bubble is useful because the database, privacy rules, workflows, backend workflows, searches, repeating groups, and editor all work together. Once you move the database to Supabase, Xano, Postgres, or another backend, Bubble becomes a clunky frontend calling an external system through the API Connector or a plugin.
That adds friction quickly:
Bubble privacy rules no longer protect the external data
Searches become API calls
Backend workflows need to coordinate with external logic
Debugging means checking Bubble logs and external logs
You now have two places where permissions can be wrong
You have to decide which system owns each record
There are exceptions. An existing Bubble app might have one heavy reporting table or one isolated data process that belongs outside Bubble. A migration might need temporary syncing between Bubble and the new database. That is fine if the scope is small and deliberate.
But if the plan for a new app is "Bubble frontend, external backend", I would usually use a frontend tool or codebase built for that instead. Bubble is a good full stack developer experience, and that is the part you lose when most of the app lives somewhere else.
Staying on Bubble is often the correct answer
Stay on Bubble when the problem is maintainability.
That usually means fixing things like:
Data types with unclear responsibility
Fields that do not explain what they store
Workflows duplicated across pages
Backend workflows that should exist but do not
Privacy rules added late or missing entirely
Searches that pull too much data into repeating groups
Reusable elements with too many unrelated inputs
Page logic that should live in a custom event or backend workflow
For example, a B2B operations app might feel like it has outgrown Bubble because every new feature takes too long. Then you inspect it and find that ownership is stored in the default Creator field, admin logic is duplicated on three pages, privacy rules are inconsistent, and every popup has its own version of the same save workflow.
That app has not necessarily outgrown Bubble. It needs better Bubble architecture.
In that case, I would probably refactor the Bubble app before migrating. Clean up the data model, move repeated logic into backend workflows, make privacy rules explicit, and test the important user types. If that gives the business another year or two of useful runway, it is probably a better spend than a full rebuild.
Migrating is correct when the product fights Bubble
Some apps should leave Bubble.
That might be true if the product needs a very custom frontend, complex collaborative editing, a specialist database model, heavy background processing, proper code-level test coverage, or deep integration with an existing engineering stack.
There is no prize for forcing Bubble to do work it is bad at.
The useful question is this: would a well-built Bubble version still feel wrong?
If the answer is no, fix the Bubble app. If the answer is yes, migration may be the right call.
I would also check whether the business is actually ready to own a codebase. Code gives you more control, but it also gives you deployments, environments, test suites, database migrations, DevOps decisions, dependency updates, and developer hiring. That can be worth it. It should not be treated as free.
Avoid the long-term hybrid app
Be very careful with half-migrating an app.
The common bad version is: Bubble frontend, Supabase database, some workflows in Bubble, some logic in Edge Functions, some records duplicated, and no clear source of truth.
This gets painful fast. A Bubble repeating group cannot search the external database like a normal Bubble data type. Privacy rules do not automatically apply. A backend workflow might update a Bubble Thing, then call an API, then wait for an external function to update another table. When something breaks, you have to debug both systems.
Sometimes a hybrid state is necessary during a migration. Keep it temporary and specific.
My preference is usually to keep the existing Bubble app running, build the new codebase in parallel, and migrate module by module. After each module, prove the data migration works for that module. Use the hybrid state to reduce cutover risk, not as the final architecture.
Choose the cutover plan based on the app
For many B2B apps, account-by-account migration can work. If each customer account is mostly separate, you can move customers one at a time, support them properly, and avoid one big launch day.
For marketplaces, social apps, communities, and B2C apps with shared data, account-by-account migration usually does not work. Users interact with the same records. Messages, payments, posts, bookings, comments, or orders may involve multiple users. You normally need dry runs, a cutover window, rollback thinking, and a clear plan for in-progress activity.
Before cutting over, decide:
When Bubble stops accepting new writes
Which records need to be locked
Whether anything syncs both ways
How you will test migrated privacy behaviour
How admins will inspect old records
What happens if the new app has a serious issue
Do this before launch week.
Rule of thumb
Stay on Bubble if the app is mostly suffering from bad Bubble architecture.
Migrate if a well-built Bubble app would still be fighting the product requirements.
Do not start a new Bubble app with an external database unless there is a very specific reason.
If you migrate, treat data migration, backend workflows, privacy behaviour, feature parity, and cutover as part of the build from day one.