Context
• Branches: Main → Dev → Testing
• Workflow: build all features in Dev → merge Dev→Main → deploy Live
• Pain: When only Feature A is ready, merging Dev pushes half-baked Features B/C too
Goal
Ship just the one finished module at a time, keep others isolated.
Questions
Has anyone used a separate feature-branch per module in Bubble? How do you merge only that branch into Main without conflicts?
Is there a way to “cherry-pick” specific changes in Bubble’s branching UI?
What other branching or environment patterns have you found reliable for deploying one feature at a time?
A production app with high reliability requirements and perhaps a team behind it will generally have the following setup:
Main
Staging
Feature 1
Feature 2
Feature 3
Main is kept ‘clean’, meaning it’s only used to deploy to live. We never develop on Main. This is so that we don’t accidentally deploy an unfinished feature to live.
We develop on feature related branches. It makes sense to group not just by feature but also if they ‘touch’ the same part of the app (e.g if two features both deal with one popup, it’s probably best to develop both in the same branch to avoid conflicts and send them live together).
When we think our feature is ready, we merge it into staging so we can test further, or perhaps so the client can test.
Then, when that’s all good, merge to main and deploy when ready.
Other best practices for version control include:
merge from parent branches early an often (e.g when working on a feature, sync from staging regularly so you reduce the risk of conflicts)
be judicious about what you change and don’t go adjusting random elements or logics unless it’s necessary
if working with other developers, communicate clearly about what you’re working on and in which branch
But, not all apps need such a setup. If it’s a smaller app with a relatively simple change or slow update cadence, maybe you can work directly on Main. I know I do sometimes. Would it be better to work on staging / a feature branch? Absolutely, but merging in Bubble is laborious and a pain.
There’s no single “right” way, but here’s the branching setup I’ve found safest (and it matches what @georgecollier suggests). I’ve also run week-by-week or per-dev branches, but this is the one that scales cleanly.
1. Recommended branch stack
Live (read-only)
└── Main ← deploy-only, always = Live
└── Staging ← integration / QA
└── feat-login
└── feat-billing
└── feat-anything
Main = deploy lane. No one builds here; merge only when you’re ready to push live.
One feature = one branch. If two features don’t touch the same element, keep them separate so they can ship independently.
Staging = team sandbox. Merge finished features up to Staging for QA/UAT.
Hotfix for emergencies. Branch off Live, patch, deploy, then flow the fix back down (Live → Staging → feature branches).
2. Keep conflicts to a minimum
Pull Staging into your feature branch often to tame conflicts while they’re small.
Bundle shared UI edits. If two features touch the same popup, keep them in the same branch.
Change only what you’re working on. Random style tweaks in other pages = instant red merge dialogs.
Need just one tiny change? Copy that workflow/page into a fresh feature branch and drop the bulky one—faster than untangling a giant merge.