Migrating your Bubble app to Next.js/Supabase and how it can go wrong

Hey everyone :waving_hand:

We’ve had a few clients recently come to us @ Not Quite Unicorns partway through a Bubble to Next.js/Supabase migration. They sometimes have 100k+ users and millions in funding, so these are actual complex apps.

We’re seeing a lot of the same and I wanted to drop some advice for other people trying to do the same thing.

The first part of migrating your app feels fast and refreshing because rebuilding UI and basic logic is relatively easy. You can use Claude Code, Cursor, v0, Lovable, etc. to get a decent-looking Next.js app quickly. You can create tables in Supabase quickly. But is a bit misleading, because most of the time, the new app has exactly the same technical debt that you’re migrating away from Bubble from.

Most Bubble apps don’t need to migrate to code, but the biggest reason they do, more than any Bubble limitations, is that they were badly built in the first place. A lot of founders are doing the exact same thing again, and are basically just moving their technical debt to a different stack (many of them would’ve been able to resolve their issues in Bubble and scaled without ever having a need to migrate!).

It’s sooooo frustrating to see people falling into this trap because in a few months after migrating they find the same kind of issues they faced on Bubble and learn that the problem was not with the platform but how their app was built.

AI code is useful, but it is not magic

People are using AI code tools to avoid understanding the Bubble app and their new code. That does not work.

Claude Code can generate a nice component. It can write an API route. It can create a Supabase table. It can help with RLS policies if you give it the right context (as an aside, don’t use RLS with direct client DB connections, it’s a security nightmare…).

If your migration plan is “export the Bubble JSON, give it to Claude, and ask it to rebuild the app”, you are probably going to have a very bad time.

The Bubble app JSON is useful (and Buildprint even more so), but it isn’t magic!

At best, it gives you a spec sheet of what exists at the moment. But when the AI agent sees it, it also takes it as an assumption that what is in the Bubble app source code should also be in the new codebase. It will almost never suggest doing things a better way / different way that’s now possible in code.

That’s your responsibility to decide, and you can only do that if you truly understand what you’re building and stay heavily in the development loop during migration.

Moving technical debt is not the same as fixing it

So, most migrations end up recreating the same technical problems in a new stack.

If the Bubble database is confusing, copying it table-for-table into Supabase does not suddenly make it good architecture, for example.

A migration is an opportunity to decide what the app actually is. It’s the only other time the business will have to reset its technical debt and design the new application based on what the application has become (rather than what it was envisioned to be when it was first built).

Some parts can for sure be copied fairly directly. But some parts always need to be entirely redesigned. That is annoying, but it is also the point. If you migrate without doing that thinking process, you can easily spend a ton of money building a cleaner-looking version of your app that has the same mess.

External backends with Bubble are where apps go to die

Another thing I see is teams trying to migrate table by table into Supabase/Xano/whatever while keeping Bubble as the frontend.

Sometimes this is fine for a very specific, contained use case. For example, if you have one heavy reporting table, or one isolated data process that really benefits from being outside Bubble.

But as a general full app migration strategy, Bubble + external backend is often where apps go to die.

Bubble owns some data, Supabase owns some data, some workflows run in Bubble, some logic runs in Edge Functions or API routes or Next server actions. Everything moving between the two systems has to pass through the API Connector or some plugin layer. The app now has two sources of truth, two permission models, two debugging surfaces. And you haven’t even moved off of Bubble!

Bubble is strong because it’s a full stack platform. Once you pull the database out, Bubble becomes an extremely clunky frontend on top of an external backend. Lots of apps we work with came to us after getting stuck here and it can almost kill their business because using an external backend just kills their development velocity.

How to migrate your Bubble app to code correctly

If you are planning a Bubble to Next.js/Supabase migration properly, you should generally build the new codebase in parallel than slowly turn the existing Bubble app into a hybrid Bubble/Supabase/Next.js situation. The new build will then catch up with product development on the existing Bubble app.

Build it module by module (exactly what a module is will depend on the app), and after each module, verify full data migration works up to that module. The other big mistake people keep running into is adding all the data migration functionality at the end. It’s a bit like how in Bubble if you save privacy rules til last you kind of screw yourself over and it creates all sorts of problems. If you later find your Bubble data structure cannot be transformed to fit the new database structure and you’ve built your whole new build logic on top of it, you’re kind of screwed.

For B2B apps, self-serve migration is generally best. You can let customers move over at their own pace, especially if accounts are fairly isolated from one another. It means they can move at a time that’s convenient, and it also means you don’t have one big cutover today (instead it’ll be a slow ramp up which helps fix any scale issues you didn’t anticipate).

For B2C apps, marketplaces, social apps, or anything where users interact heavily with shared data, self-serve migration obviously doesn’t make sense. You usually need a proper cutover plan after dry running the data migration and testing the new system properly.

There are exceptions to the above of course, but the main principle is that the migration needs to be done thoughtfully, not just passing your app logic to Claude Code and hoping for the best.

Final thought

Most Bubble apps don’t need to leave Bubble. The stories of ‘I migrated my Bubble app to code in two weeks!’ are mostly crap from people without apps that are running at any kind of serious scale or complexity (and the people advertising that they’ll migrate your app based on your JSON file are basically vibe coding it and doing exactly what I’m suggesting not to do).

But if you are going to migrate to Next.js/Supabase, take it slowly and do it properly (ideally with a team that knows both Bubble and code). That will give you the best chance of success.

How rare (or not) are competent next.js developers in the Bubble scene?

What exactly are the bad practices? Lots of vagueposting here.

You should basically never give AI direct access to Bubble app JSON (except possibly for UI).

Self explanatory

As above!