Blog
·9 min read

Replacing Bubble Plugins in a Code Migration: A Practical Checklist

Replacing Bubble plugins starts with understanding what each plugin does in your live product. A custom-code library or provider SDK may cover part of the job, but you still need to rebuild the surrounding workflows, permissions, data handling and failure behavior.

For each plugin, map the capabilities you actually use, choose what to retain or replace, and define evidence that the new version works. That gives founders a scope they can review and engineers a clear definition of done.

This checklist focuses on plugin replacement within a Bubble-to-code migration. It is useful once you are scoping a rebuild or moving one part of an existing app to code.

What happens to Bubble plugins when you move to code?

A Bubble plugin is built to work inside Bubble. During migration, its role may be taken over by a UI component, a server-side integration, an official provider SDK, or custom business logic. The external service behind it may stay exactly where it is.

For example, replacing a payment plugin does not automatically require changing payment providers. Replacing a calendar element does not necessarily require changing the stored date model. Those are separate decisions, and bundling them into the same release adds work that should be explicitly agreed.

Bubble’s plugin documentation describes elements, actions, events, data sources, authentication and background scripts. One installed plugin can therefore represent several pieces of product behavior. Counting installed plugins is useful for discovery, but it is a poor substitute for tracing their use.

1. Map used capabilities to real user journeys

Start in the Bubble editor with the installed plugins, then inspect the pages, reusable elements and workflows that use them. Include backend workflows and API Connector calls. Record the version and configuration currently used in production, rather than assuming the latest marketplace description matches your app.

Create one worksheet entry per used capability. A payment plugin used for checkout, subscription changes and refunds needs separate entries because each has different inputs, effects and failure cases.

FieldWhat to record
DependencyPlugin, version, capability and the pages or workflows that invoke it.
ContractInput fields, returned values, exposed states, events and the downstream steps that consume them.
BoundaryBrowser or server execution, external provider/account, and where credentials are stored. Record secret locations, never secret values.
EffectsRecords written, files created, messages sent, payments requested or access granted.
DecisionProposed replacement, what deliberately changes, and the engineer responsible.
EvidenceAcceptance tests, observed results, cutover conditions and when the old integration can be retired.

Trace a complete journey. For a booking calendar, selecting a date might update an exposed state, start a pricing workflow, create a reservation and send a confirmation. Rebuilding only the calendar display leaves most of that dependency untouched.

Bubble’s element documentation makes this distinction concrete: plugin elements can publish states and trigger workflow events. Capture those connections before choosing a replacement component.

2. Choose a replacement for each layer

UI elements

For calendars, maps, charts and upload controls, compare interaction behavior as well as appearance. Check keyboard use, mobile layout, empty states, validation, loading, cancellation and errors. Confirm the exact values the component returns, including date/time interpretation, units and empty values.

A date picker that displays the same day but saves a different instant can break bookings. A file uploader that looks identical can still change who is allowed to retrieve the file. Write those expectations down before implementation.

Provider integrations

Where a plugin wraps an external service, first decide whether to keep that provider and account. Then compare the provider’s supported API or SDK with the operations the app actually uses. An SDK provides API access; your application still needs authorization checks, business rules and error handling.

Preserve the meaning of provider object IDs and their relationship to app records when that is part of the agreed design. Treat an account or provider change as separate migration work. The Bubble data migration checklist covers record identity, relationships, files and access in more detail.

Server actions and API Connector calls

Identify where each action executes and what later workflow steps expect it to return. Bubble supports client-side and server-side plugin actions, so a browser-only replacement is not appropriate for every capability.

For API Connector calls, record the HTTP method, authentication, headers, request fields, response fields and error paths. Bubble routes these calls through its servers by default, with restricted exceptions. Keep secrets and privileged operations on a suitable server-side boundary in the replacement.

Use test environments when checking behavior. Initializing an API Connector call by sending a live request can create, update or delete data. Bubble also offers manual-response initialization without a request. A production write endpoint is not a harmless way to discover a response shape.

Unused or low-value dependencies

An installed plugin may no longer support a live feature. Verify references before marking it unused, and obtain product approval before retiring the behavior. For a low-traffic admin feature that still works well, keeping it on Bubble may be reasonable. The hybrid migration guide explains the trade-offs of maintaining both systems.

3. Write acceptance tests before declaring a replacement complete

Define tests around outcomes users and operators can observe. The following examples are suggested test cases, not results from a client migration.

  • Calendar: selecting, changing and clearing a date produces the agreed stored value and triggers the intended downstream workflow. Test the time zones the product supports.
  • Uploader: an authorized user can upload and retrieve a file; another account cannot retrieve a private file; a failed upload leaves a recoverable state.
  • Email integration: the intended recipient receives the right template and links in the test environment. Replaying the same business operation does not send an unintended second message.
  • OAuth integration: a verified provider identity maps to the intended existing account. Denied consent, expired access and logout produce the agreed behavior.

For every critical journey, cover success, invalid input, insufficient permission and a provider failure. If a new design intentionally changes old behavior, record that as an approved product change rather than calling it a like-for-like replacement.

4. Treat payment retries and webhooks as separate problems

Consider an illustrative subscription flow: a user checks out, the provider confirms payment, and the app grants access. Replacing the Bubble payment action with an SDK call only covers part of that flow.

The replacement also needs a reliable way to interpret provider events and update the correct account. Stripe’s webhook guidance says events can arrive more than once and are not guaranteed to arrive in order. Signature verification requires the unmodified request body.

Test at least these conditions in the provider’s test environment:

  • An invalid webhook signature makes no business-state changes.
  • A duplicate or concurrent delivery does not apply the same entitlement change twice.
  • A delayed or out-of-order event does not incorrectly restore or remove access.
  • A failed processing attempt can be retried without repeating the completed business effect.

Stripe’s idempotent request guidance addresses retries of supported API requests. It does not automatically deduplicate your webhook handler or make every downstream action safe to repeat. Define protection for both outbound requests and incoming event processing.

The same distinction matters for order creation, notifications and other integrations with external side effects. A successful HTTP response is only one piece of the acceptance evidence.

5. Plan the handover between old and new integrations

When Bubble and custom code coexist, decide which system owns each external effect at each stage. Two active webhook handlers can both try to grant access. Two scheduled workflows can both send a reminder. Testing in parallel is useful only when it cannot accidentally duplicate production effects.

Document the cutover steps for that dependency: routing changes, pending jobs, provider callbacks, event processing and the checks that permit the next step. Set a clear owner for the decision.

Also define what recovery means after the replacement has processed real activity. Returning traffic to Bubble does not undo payments, messages or newly written records. The recovery plan must account for those effects and reconcile relevant state before the old path resumes.

Retire the old plugin, subscription or credentials only after confirming that no remaining workflow depends on them and the agreed recovery window has closed. Keep a record of the replacement, its configuration locations, tests and operational owner.

What to ask your migration team to hand over

Ask for a capability inventory with no unexplained gaps, an explicit keep/replace/retire decision, the acceptance evidence for critical journeys, and a runbook that explains ownership during cutover and recovery. Include intentional behavior changes so future engineers can distinguish design decisions from regressions.

Bubble to Code brings together practicing Bubble developers and software engineers. The team’s published approach covers plugins, integrations and business logic, with integration tests for critical auth, billing and webhook paths.

Frequently asked questions

Can I reuse a Bubble plugin in a custom-code app?
Do not assume the plugin itself is portable. Check its implementation, license and runtime dependencies. A separate library or external API behind it may be reusable, but Bubble-specific states, actions and workflow connections still need a replacement.
Does every plugin need a one-to-one code equivalent?
No. One plugin may become several components or services; several plugins may be replaced by one well-defined integration. Judge the result against the required behavior and maintainability, rather than matching the number of packages.
Do we have to change payment or email providers?
Not necessarily. You can often keep a provider while replacing the Bubble integration layer. Confirm account ownership, supported APIs, existing IDs and callback requirements before treating that as the plan.
What if a plugin has no obvious replacement?
Identify the exact capability the product needs. Then compare a custom implementation, an alternative service, retaining that feature on Bubble, or retiring it with product approval. Resolve uncertainty with a small test of the risky behavior before committing the whole rebuild.

Sources

  1. 01What plugins can do · Bubble Docs
  2. 02Building plugin elements · Bubble Docs
  3. 03Building plugin actions · Bubble Docs
  4. 04The API Connector · Bubble Docs
  5. 05Receive events with webhooks · Stripe Docs
  6. 06Idempotent requests · Stripe Docs

Keep reading

Bubble to Code is an independent service. Not affiliated with, endorsed by, or sponsored by Bubble Group, Inc.