AppSavvyBook a call
Bubble Migration

Bubble to Next.js: A Step-by-Step Migration Guide for Founders

How to migrate a Bubble app to Next.js without big-bang rewrites. The target architecture, the six phases, the gotchas, and how to keep shipping while you migrate.

Will Driscoll12 min read

Most Bubble-to-code migration guides on the internet are written by agencies who haven't actually done one. They describe a fantasy where you "just rebuild the app", flip a switch, and everything works. In practice, that approach is how migrations break businesses.

This guide describes how we run migrations at AppSavvy: the target architecture we pick most often, the six phases of a real migration, the common gotchas, and how to keep shipping product the whole time. It's the same playbook we used to migrate Ohana, the Stripe Connect marketplace now on track for $60M+ in annual payment volume.

The target stack: Next.js + Supabase + Trigger.dev

There's no single right stack for every app, but for the majority of mid-stage Bubble apps, the stack we land on looks like this:

  • Next.js on Vercel for the frontend and server actions
  • Supabase Postgres for the database, with row-level security (RLS) for permissions
  • Drizzle ORM in TypeScript as the source of truth for the schema
  • Trigger.dev for any async, scheduled, or retryable work
  • Stripe for payments
  • Resend or Postmark for transactional email

This isn't novel. It's a boring, well-supported stack with first-class TypeScript everywhere. Boring is the point.

The reason this combination wins for migrations specifically: every part of it has a clean equivalent to something you already have in Bubble. Pages map to Next.js routes, Data Types map to Postgres tables, workflows split between server actions (synchronous) and Trigger.dev tasks (async), privacy rules map to RLS policies. The mental model isn't a leap.

What migration actually means

A migration is not a rewrite. The distinction matters because it changes how you plan and price the work.

A rewrite assumes you're going to reproduce everything in the existing app, 1:1, in a new technology. It's a contract for "make the new thing identical to the old thing." That's the dumbest possible goal - if the existing thing was perfect, you wouldn't be migrating.

A migration assumes you're going to use the existing app as a reference for what the product does today, then redesign it around what the product needs to do tomorrow. Some things get carried forward as-is. Some things get rebuilt better. Some things get cut entirely because they were never used.

The biggest predictor of migration success is whether you treat it as a migration or a rewrite. (See also: Why 1:1 carbon-copy migrations fail.)

The six phases

We break every Bubble migration into six phases. Each phase has a clear deliverable you can use - even if you stop after that phase and never proceed.

Phase 1: Discovery (1-2 weeks)

We audit the live Bubble app end-to-end. Every Data Type, every workflow, every option set, every plugin, every page, every reusable element. We document what each thing does, where it's used, what depends on what. Critically, we also flag the AMBIGUOUS items: workflows that look broken, data that contradicts itself, oddities that need a decision before they can be migrated.

The output is a written discovery document that's about 50-150 pages depending on app size. It's yours whether or not you proceed with us. Many founders take it to their internal team and use it for their own refactor work.

Phase 2: Architecture (2-3 weeks)

We design the target system before any application code lands. That means:

  • Postgres schema in TypeScript via Drizzle ORM
  • Row-level security policies (the equivalent of Bubble privacy rules - see our translation guide)
  • Auth and permissions model (built on Supabase Auth most of the time)
  • Async work strategy: what becomes a Trigger.dev task, what stays synchronous
  • Sub-processor list (hosting, email, payments, file storage)

The architecture phase is reviewable. You can take the schema design to your team or to another engineering partner and get a second opinion before any feature code lands.

Phase 3: Foundation (1 week)

This is the boring infrastructure phase. Supabase project provisioned, Vercel deployment connected, Trigger.dev workers configured, GitHub Actions for CI, secrets management, observability, error tracking. It's all standard but it has to be done correctly before any feature code lands or you'll be paying a price for it at month six.

We do this in a single concentrated week so it doesn't drag out.

Phase 4: Vertical slice migration (8-14 weeks)

This is where the actual feature work happens. We rebuild your app one workflow at a time. Each "slice" is a complete vertical: schema + RLS + server logic + UI + tests. The slices are sized so each one ships within 1-2 weeks.

Critically, your Bubble app stays live the entire time. Users don't see the new app until each slice is fully cut over. There's no big launch day.

Phase 5: Data migration (1-2 weeks)

Idempotent, chunked, resumable imports from Bubble's data API into Postgres. We design this so it can be run multiple times without duplication, so it can be paused and resumed, and so it handles edge cases (soft deletes, option sets, recursive foreign keys) without silently corrupting data. See our deeper article on data migration.

Phase 6: Cutover and partnership (1 week + ongoing)

DNS switches. The Bubble app becomes read-only. We stay on for the first month minimum to monitor production, fix the surprises, and hand over a system your team can own. Ongoing partnership is optional.

How to keep shipping during migration

The single biggest reason migrations fail isn't technical - it's that the product team can't ship features during the migration. The business loses momentum, the founder loses patience, and the migration gets killed before it finishes.

There are two patterns that work to avoid this:

Pattern 1: feature freeze on the slices being migrated

If we're migrating the auth slice this week, the Bubble auth flow gets a feature freeze for that week. Your team focuses on other slices that aren't actively being touched. The feature freeze rotates weekly.

This works best when your product roadmap is large enough that there's always something else to work on.

Pattern 2: parallel feature development on both apps

If you have to ship a critical new feature mid-migration, we build it on both Bubble (for current users) and on the new code app (so it ships when the slice cuts over). It's expensive but it lets the business keep moving.

Most teams use Pattern 1 90% of the time and Pattern 2 sparingly.

Common gotchas

The seven things that go wrong on migrations more often than founders expect:

  1. Custom code escape hatches with no documentation. Every Bubble app has these. They need to be tracked down and re-implemented properly in the new app.
  2. Privacy rules that "work" because of UI restrictions. Bubble apps often rely on the UI not exposing a field rather than privacy rules enforcing it. Postgres RLS is strict - you find out fast which fields were actually protected.
  3. Plugin behaviour that isn't replicable. Some Bubble plugins do non-trivial things. The replacement code path needs to be designed, not just translated.
  4. Workflows that race themselves. Bubble's eventual-consistency model hides race conditions. Once you're in Postgres with proper transactions, the bugs become visible.
  5. API workflows that became your background job system. Triggers.dev handles this cleanly but it's a different mental model.
  6. Custom states and conditional formatting that became business logic. Often these are doing things the new app should do in the data layer, not the UI.
  7. The "we'll figure that one out later" item. Every Bubble app has 2-3 of these. They need to surface in discovery, not month four.

What to do next

If you've decided you want to migrate, start with discovery. The Bubble migration playbook PDF gives you the shape of how we run discovery and the rest of the phases.

If you'd rather have a senior engineer look at your specific app first, book a 30-minute discovery call or request a free audit.

Read next: Bubble vs Code cost comparison at scale and How to audit your Bubble app before migration.

Got a Bubble or Canvas app you’d like a second pair of eyes on?

30-minute discovery call. We’ll look at your app live and tell you honestly what we’d do next.

Or grab the Bubble migration playbook PDF.