Skip to content
Menu

Bubble to code migration

Phase by phase, the app stays up

It was fast to build. Now it is what holds you back.

The app works and has customers. But the bill grows with traffic, public pages take seconds to load, and Google indexes them badly. And the first time you have a serious conversation with an investor or a buyer, someone asks what happens if the platform changes its pricing or disappears.

What it costs you, measured

Measured 27 October 2026

It is not an impression. It takes thirty seconds to measure.

1,371KB

A public page served by Bubble delivers the platform runtime before it shows the first word. It does not depend on what you put on the page. The same page written in code and served as a static file delivers almost nothing.

JavaScript delivered before the first word

On Bubble
1,371 KB
In code
5 KB

Your browser console, on your own site

const kb = n =>
  Math.round(n / 1024) + ' KB';
const size = a => a.reduce(
  (t, x) =>
    t + x.encodedBodySize,
  0
);

const all = performance
  .getEntries()
  .filter(x =>
    x.encodedBodySize);
const js = all.filter(x =>
  /\.js(\?|$)/.test(x.name));
const nav = all.find(x =>
  x.entryType === 'navigation');
const ms =
  Math.round(nav.loadEventEnd);

console.table({
  total: kb(size(all)),
  javascript: kb(size(js)),
  load: ms + ' ms',
});
manual.bubble.io, performanceChecked 27 October 2026

There is something else you cannot see. A marketing page on Bubble can trigger database queries on every view, including for Google's crawlers. Each one costs workload units, which is money, for visitors who asked for nothing. The same page served statically costs zero per visit, however many people read it.

I am not proposing a rewrite from scratch, handed over in one piece six months from now.

Not because it cannot be done, but because that is how migrations fail: you pay for months without seeing anything, and at the end you get something that no longer resembles what you had.

The route

Five phases. You buy one at a time.

The right-hand column says what state the app is left in at the end of each phase. You do not buy the whole route up front. You buy the audit. After the audit you decide whether to do phase 1, and only after you have seen phase 1 delivered do you decide whether we go further.

  1. 00

    Audit

    Untouched

    I read your app: the data model, the workflows, the plugins, the integrations. Out comes a document with what translates directly, what has to be rethought, the plan by phase, and what it costs you per month afterwards.

  2. 01

    The public layer

    Running

    The public site, the marketing pages, the landing pages and the blog leave the platform. For users nothing changes.

  3. 02

    The reads

    Running

    Pages that only display data move to code. The platform stays the source of truth.

  4. 03

    The writes and the payments

    Running

    The flows that bring in data and money move to code, one at a time.

  5. 04

    Accounts and the cutover

    Real risk

    Users move across, the old platform is switched off. The only moment with real risk. At the app I moved, that window was under an hour, at the volumes it had: the audit measures yours.

jemshitmavlyanov.com after the migration

One that was done

A video academy, moved in full.

Accounts, authentication, cart, payment, access that expires after six months, a certificate and an admin panel. Nine languages, with Russian audio and subtitles for each.

jemshitmavlyanov.comSee it on Bubble, archived

What hurts and cannot be avoided

04

Four things nobody can work around.

  1. 01

    Passwords

    User passwords do not leave the platform. Anyone who promises otherwise has either never done it or is not telling you everything. At phase 4, people reset their password. That is not a technical detail, it is an email that has to be written well and sent at the right moment, or you lose users who have not logged in for three months.

  2. 02

    Two systems in parallel

    Between phase 2 and phase 4 both are running. At any moment only one is the source of truth, and the audit decides which and when it moves. If that is not decided out loud, you get data that does not match, and that is expensive to repair.

  3. 03

    The plugins

    Some have no direct equivalent in code. Each one is either rewritten, replaced with a service, or cut because nobody was using it anyway. The split is never even: in the app I moved, eleven plugins came to four that only called an API, which are an afternoon each, and seven that did something in the browser, which are the ones that cost. That list appears in the audit, not halfway through the project.

  4. 04

    The queue nobody can see

    Anything scheduled for the future lives only on the platform, and there is no way to list it or export it. Access that expires six months after purchase is not a field checked when the page loads: it is one scheduled job per order, sitting in a queue, dated months ahead. Miss it and access never expires on the new system, with nothing in any log to say so, until the first person who should have been locked out writes in. It is rebuilt from the data rather than from the queue, because the dates are on the records, but only if someone knows to look.

Before you decide to leave

One day, 350 EUR

Most Bubble apps are slower than Bubble makes them.

Part of what you are paying for is the platform and part of it is the app. I measure yours and tell you which is which, in writing, before you decide anything.

What the app does to itself

Fixable
  • Searches that load a whole list in order to count it, and the ones that run again on every view
  • Repeating groups that query inside the row instead of once at the top
  • Workflows that fire on every page load because nobody put a condition on them
  • Plugins loaded on every page for the one screen that uses them
  • Images served at the size they were uploaded at

What nobody can move

The floor
  • The runtime. 1,371 KB arrives before your first word and no setting removes it
  • A public page renders by asking the database, so a crawler that asked for nothing still costs you
  • The bill follows how much the app is used, not what you built. Tuning moves the number, not what it is tied to

The audit ends in one of two sentences. Fix what the app is doing to itself and stay, or the app is already as fast as the platform allows and the only thing left is to leave. I write the one that is true, and if it is the second the 350 EUR comes off the 600 below.

See the whole day

The migration audit

600 EUR

Two days

Ask for an audit

You get a document with:

  • An inventory of the app: data types, fields, relationships
  • The workflows, what each one does and what happens to it
  • The plugins and integrations, with their equivalent in code or the lack of one
  • The plan by phase, with what can be delivered on its own
  • What it costs you per month afterwards, against what it costs you now

If we go further, the 600 EUR comes off the price of the project.

If we do not, you keep the document. It is yours, and you can hand it to anyone else.

When to stay where you are

Not every app belongs in code.

If you still do not know whether the product has a market

The speed at which you can change things is worth more than the bill. Stay.

If the app is internal, with a few dozen users

Nobody is looking for it on Google. There is nothing to gain.

If the monthly bill is small and not growing

If it does not hurt, it is not a problem.

What happens after the first message

Three steps, and no sales funnel.

  1. 01

    You write to me about the app you have and what bothers you most about it. I answer the same working day, with a question or two.

  2. 02

    If it looks like it makes sense, we talk for thirty minutes. No deck, and no proposal prepared in advance.

  3. 03

    If it still makes sense after that, I send you an audit proposal with a start date. That is all.