# ShareTalent: migrating a live non-profits marketplace to Bubble's new responsive engine.

> Seventeen months as lead dev, zero data loss across the responsive-engine migration of a live non-profits marketplace. ShareTalent connects non-profits with freelancers. When I joined, the app was on Bubble's old responsive engine with live users and live revenue. The migration to the new engine shipped on time and inside budget, mobile responsiveness alongside. The work that followed was a security audit pass, a UI/UX rebuild against the client's Figma, performance optimisation ahead of Bubble's move from capacity-based pricing to Workload Units, and the user-feedback iterations that earned me the rebuild of the next version of the product.

- Client: ShareTalent
- Industry: Marketplace · non-profits
- Timeline: Jan 2024 to May 2025
- Status: retired
- Stack: Bubble.io, Stripe, Mailchimp, Postmark
- Author: Anish Gandhi, https://anishgandhi.com/about/
- Canonical page: https://anishgandhi.com/work/sharetalent/

## Outcomes

- Engagement: 17 months (Jan 2024 to May 2025)
- Role: Lead dev (direct client)
- Data loss: Zero (live users preserved end to end)

## A live marketplace, migrated in place

_Jan 2024 · live users, live revenue_

ShareTalent is a two-sided marketplace that connects non-profits with freelancers who want to work for them. Non-profits post the work, freelancers list their skills and portfolios, payments and contracts run through the platform. I came on as lead developer in January 2024. The app was already live with paying users on Bubble.io's old responsive engine. The migration to the new engine was the first scope: rebuild every page against the new model, keep the live users and live data and live revenue intact, ship mobile responsiveness alongside, fix the bugs that real customers had been living with.

The engagement stretched to May 2025. Seventeen months as lead developer on a single product, across the migration, a security audit pass, a UI and UX rebuild against the client's Figma, performance optimisation ahead of Bubble's pricing migration from capacity-based plans to Workload Units, and the user-feedback iterations that kept the product getting better between the headline pieces of work.

> *Migrating a live Bubble.io app between responsive engines is not a refactor.* The data layer and the workflows survive untouched. The presentation layer is gone and rewritten, page by page, against a different model. The old engine was percent-based positioning with manual breakpoints. The new engine is row-and-column containers closer to modern flexbox. The migration is mostly a careful rebuild of every layout.
> (Anish Gandhi)

## The migration: every page rebuilt against the new responsive model.

The old Bubble responsive engine asked you to lay out pages with absolute percentages and manual breakpoints, and then to fix the layout for narrower viewports by hand for every element. It worked for the desktop view the original developer had targeted, but it was brittle the moment the viewport sized to something the page had not been built for, and it made mobile responsiveness a per-page rebuild rather than a property of the layout.

The new responsive engine inverted the model. Pages compose with row and column containers that handle wrapping, alignment, and minimum and maximum sizes the same way modern CSS flexbox does. Responsive behaviour falls out of the container hierarchy rather than being painted on top of it.

**Engine migration** (what moved, what stayed)

- **Stayed put**. Before: nothing touched them. Now: data types, workflows, API Connector calls, Privacy Rules..
- **Rewritten**. Before: percent positioning, manual breakpoints per element. Now: every layout re-derived against the new engine, every element re-bound to the same fields..
- **Alongside**. Before: open bugs the live users had been carrying. Now: resolved in the same pass..

None of it produced visible new features. All of it determined whether the product would feel modern for the next two years or stay brittle for them.

![The ShareTalent onboarding step Get started as a freelancer showing profile tips and Continue or Switch to Organization options, rebuilt on Bubble's new responsive engine](https://anishgandhi.com/images/projects/sharetalent-2.jpg)

![The ShareTalent onboarding step Get started as an organization with profile tips and Continue or Switch to Freelancer options, the mirror entry for the non-profit side of the marketplace](https://anishgandhi.com/images/projects/sharetalent-5.jpg)

## Mobile-responsive, shipped alongside the migration.

The original product was not mobile-responsive. The home page rendered acceptably on a phone, but the rest of the application (onboarding, profile editing, project posting, the dashboards) had been built desktop-first and never finished for mobile. Migrating to the new engine without making the app mobile-responsive at the same time would have left a second migration on the table for later.

Doing both passes together was the right call. Every page rebuilt against the new engine got its mobile layout in the same sitting. Row containers with wrap-on-overflow handled the desktop-to-tablet collapse. Column containers with conditional visibility handled the table-to-card transformations on phones. Image and form elements got min-width and max-width bounds so they sized down without breaking the surrounding flow.

> *Mobile responsiveness on Bubble.io's new engine is mostly a property of the container tree, not a per-element fix.* Get the parent rows and columns right with sensible min and max widths, and the children behave. The temptation is still to fix things at the element level when something looks off. The temptation is almost always wrong on the new engine.
> (Anish Gandhi)

![Two ShareTalent mobile views shown side by side: the freelancer project browse list on the left and the navigation drawer on the right, both rendered cleanly on a phone after the responsive rebuild](https://anishgandhi.com/images/projects/sharetalent-6.jpg)

## The security audit: Stripe key, Google Maps key, webhooks, and Privacy Rules.

After the migration stabilised, I ran a security pass across the application. The list of issues in the inherited codebase was longer than I expected. Four matter enough to name.

**Audit findings** (4 found · 4 closed)

- **The Stripe secret key was leaking through client-side API calls.** Not the publishable key, which is designed to be public. The secret key, which Stripe's documentation says must never leave the server. A previous developer had wired Stripe calls through the API Connector configured to run from the browser, so the secret key was a request header on every network call any unauthenticated visitor could read. The fix was moving every Stripe call to a server-side backend workflow, then rotating the key. The most consequential issue in the audit and the one I would not have wanted to find a week later.
- **The Google Maps API key was not domain-restricted.** The key worked from any origin, so anyone could lift it from the page source and run requests on ShareTalent's billing. I restricted it to the production and staging domains in the Google Cloud Console. The cost of the fix was zero. The cost of leaving it was open-ended.
- **The Stripe webhook receiver was not validating signatures.** The backend workflow read the event payload without verifying that Stripe had signed it, so anyone with the webhook URL could have posted fake events into it. I added signature verification using the webhook secret, so every incoming event has to prove where it came from before any database write happens.
- **Privacy Rules were under-scoped on several data types.** Read access on a few data types was wider than the product required, so any authenticated user could query rows that should have been scoped to their own account. I tightened the rules to the real read-access requirement per data type and added the missing Current User constraints.

None of these issues had caused a known incident. All four would have eventually. The discipline of running a security pass after a migration is the kind of audit that does not bill back to the client in features but pays back in incidents that do not happen.

> *The four things to check first on any inherited Bubble.io codebase are key handling in console logs, third-party API key scoping, webhook signature verification, and Privacy Rule scoping.* All four are easy to get wrong, easy to leave wrong, and invisible until an attacker (or an honest auditor) goes looking.
> (Anish Gandhi)

## UI and UX, implemented against the client's Figma.

Alongside the migration the client had a Figma file with UI and UX improvements they wanted shipped. Some of it was visual polish, some of it was small interaction redesigns, some of it was new flows the original responsive engine had made too painful to build. The migration to the new engine was the lever that made the Figma work cheap rather than expensive: layouts that would have been per-page hacks on the old engine were properties of the container tree on the new one.

The work was the disciplined kind: pixel-faithful implementation of the Figma where the Figma was definitive, plus the judgment calls about responsive behaviour and edge states that the Figma did not specify. The product team's design intent landed in the live app without me redesigning it along the way.

![The ShareTalent freelancer onboarding step 2 of 7, Categories and Skills, showing a pill grid of selectable categories like Design and Creative and Marketing across the screen](https://anishgandhi.com/images/projects/sharetalent-4.jpg)

![The ShareTalent organisation onboarding step 2 of 3, Organization profile, with fields for logo upload, organisation name, tagline, and overview](https://anishgandhi.com/images/projects/sharetalent-3.jpg)

## Performance optimisation ahead of Bubble's Workload Units pricing.

Around the same period, Bubble.io announced a pricing migration from capacity-based plans to Workload Units, the metered model that charges per workflow execution rather than per app size. Apps that had been comfortable on the old pricing could become surprisingly expensive on the new one if the workflow patterns were inefficient: lazy database reads, ungrounded searches, and unbounded scheduled workflows all show up in the WU bill in a way they did not show up in the capacity bill.

I audited the application's workflow patterns against the new pricing model. The hottest paths got the standard treatment: server-side database constraints replacing client-side filters, paginated repeating groups replacing "all rows" lists, scheduled backend workflows scoped to actual change windows instead of running on a blanket interval, and the search-index Bubble feature applied where it actually helped instead of on every list by reflex. The app was ready for the pricing migration before the migration arrived, with the cost trajectory under control rather than discovered after the bill jumped.

> *The shift from Bubble.io's capacity pricing to Workload Units rewards the kind of workflow discipline that the old pricing model tolerated.* An app that ran fine on capacity can run expensively on WU if no one has read its hot-path queries with an honest eye. The audit pays back the first month it lands.
> (Anish Gandhi)

![The ShareTalent freelancer onboarding review page with a seven-step progress indicator and a 29 percent completion ring, listing About, Categories and Skills, Work Experience, Portfolio, Payment Settings, Education, and Photo and Bio sections](https://anishgandhi.com/images/projects/sharetalent-7.jpg)

![The ShareTalent organisation onboarding review page with a three-step progress indicator and a 25 percent completion ring, listing General Info, Organization Profile, Account Security, and Billing and Payments sections](https://anishgandhi.com/images/projects/sharetalent-11.jpg)

![The ShareTalent freelancer Payment settings step showing an hourly rate input, the platform fee deduction, and the net amount the freelancer would receive on a Save and continue page](https://anishgandhi.com/images/projects/sharetalent-8.jpg)

![The ShareTalent Add employment modal inside the onboarding flow, with fields for company, role, location, start and end dates, and a description for structured work history](https://anishgandhi.com/images/projects/sharetalent-9.jpg)

## The ongoing iterations, then the rebuild from scratch.

The headline pieces of work (the migration, the security pass, the Figma implementation, the WU optimisation) anchored the engagement. The work that ran in between them was the steady stream of improvements that came out of real user feedback: small flow adjustments where users were dropping off, copy tweaks where the onboarding language was confusing, fixes for edge cases the testing pass had missed, and the kind of incremental polish that compounds into a product that feels considered.

The next chapter of the engagement was the founder planning a rebuild of the product from scratch on a clean Bubble.io foundation. The version this case study describes has since been retired in favour of that rebuild. The rebuild itself is a separate engagement and a separate case study. What this page is about is the part where, after a careful migration, a thorough security pass, a faithful Figma implementation, and a year of iteration on top, the client trusted me with the next version as well.

![The ShareTalent Add portfolio Item modal with fields for project title, description, category, and image upload](https://anishgandhi.com/images/projects/sharetalent-10.jpg)

> Anish is an absolutely incredible Bubble.io developer to work with. What stands out most is his ability to consistently achieve deadlines, go above and beyond with communication, and produce incredible work.
> (The founder, ShareTalent)

## What changed

ShareTalent shipped on the new Bubble.io responsive engine on time and within budget, with the live user base preserved end to end and mobile responsiveness as a side effect of the rebuild. The security audit pass surfaced four issues that mattered and fixed each one. The Figma-driven UI and UX work landed without redesigning the client's intent along the way. The Workload Units optimisation pass set the app's cost trajectory before the pricing migration arrived. The relationship continued past the migration into ongoing development and maintenance.

The version of the product this case study describes has since been retired in favour of a from-scratch rebuild on a clean Bubble.io foundation, which I am the lead engineer on as a separate engagement.

Seventeen months as lead developer on a single product, with the client trusting me with the rebuild on the back of it, is the kind of relationship that does not happen by accident.

**What I'd do again**

- **Take the migration scope seriously.**
- **Do the security pass.** that nobody specifically asked for.
- **Implement the client's design intent.** without redesigning it.
- **Audit performance ahead of pricing changes.** that are visible on the calendar.
- **Let the trust compound.** on the back of careful first work.

---

Work with Anish: https://anishgandhi.com/connect/
