What Uber Actually Does
Uber connects riders who need transportation with drivers who have cars. The product loop is a rider requests a ride, nearby drivers are notified, a driver accepts, both parties track each other's location in real time, the ride happens, payment is processed automatically, and both parties rate each other. The magic is in the real-time coordination and the elimination of payment friction.
Building a full Uber replica is one of the most complex projects you can attempt on any platform. The real-time location tracking, route optimisation, surge pricing, and driver dispatching algorithms are genuinely hard problems. But here is the thing: most people building an "Uber clone" do not actually need all of that. They need a service marketplace with location awareness and automated payments. That is very buildable on Bubble.
Core Features Worth Cloning
Focus on what makes a ride-hailing or on-demand service app functional. You need ride or service requests with pickup and dropoff locations, a matching system that connects requests with nearby providers, real-time status updates for both parties, automated fare calculation and payment, rating and review systems, and separate interfaces for riders and drivers. Skip surge pricing algorithms, complex route optimisation, carpooling and ride-sharing logic, driver heat maps, and the scheduled rides feature. Those are optimisation layers, not core functionality.
Data Architecture in Bubble
Your data model needs to support two distinct user roles and the real-time transactions between them.
The User data type extends Bubble's default with role (option set: rider, driver, both), profile_photo (image), phone (text), average_rating (number), and total_rides (number). Keep a single User type with role flags rather than splitting into separate types. This simplifies authentication and lets users switch roles.
The Driver Profile data type links to User and adds vehicle_make (text), vehicle_model (text), vehicle_colour (text), license_plate (text), license_photo (image), insurance_document (image), is_verified (yes/no), is_online (yes/no), current_location (geographic address), and stripe_connect_id (text). This is a separate type from User because not every user needs these fields, and it keeps your User table lean for search performance.
The Ride data type is your central transaction record. It needs rider (User), driver (User), pickup_location (geographic address), dropoff_location (geographic address), pickup_address_text (text), dropoff_address_text (text), status (option set: requested, accepted, driver_arriving, in_progress, completed, cancelled), fare_estimate (number), final_fare (number), distance_km (number), requested_at (date), accepted_at (date), started_at (date), completed_at (date), and stripe_payment_id (text).
The Rating data type stores ride (Ride), from_user (User), to_user (User), score (number 1 to 5), and comment (text). Link ratings to rides so each ride can have exactly two ratings, one from each party.
The Driver Location Log data type tracks driver (User), location (geographic address), timestamp (date), and is_latest (yes/no). This gives you location history without constantly updating the Driver Profile record, which is more efficient in Bubble's database.
Workflows That Power the App
The ride request workflow fires when a rider submits pickup and dropoff locations. Create a new Ride with status set to requested. Calculate the fare estimate using the distance between the two geographic addresses (Bubble has a built-in geographic distance operator). Then find available drivers. Do a Search for Driver Profiles where is_online is yes, is_verified is yes, and current_location is within a defined radius of the pickup location. Send notifications to matching drivers via the push notification plugin or a real-time polling mechanism.
The driver acceptance workflow triggers when a driver taps accept on a ride request. Change the ride status to accepted, set the driver field to the current user, record accepted_at, and notify the rider. Use a condition to check that the ride status is still "requested" before allowing acceptance. This prevents two drivers from accepting the same ride. Bubble processes workflows sequentially, so adding an "Only when Ride's status is requested" condition handles this race condition for most use cases.
The ride status progression workflow moves through stages. When the driver arrives at pickup, they tap "Arrived" which sets status to driver_arriving. When the rider gets in, the driver taps "Start Ride" which sets status to in_progress and records started_at. When they reach the destination, "Complete Ride" sets status to completed, records completed_at, calculates final_fare based on actual distance or time, and triggers payment.
The location tracking workflow is where Bubble gets creative. True real-time GPS tracking requires either a native wrapper like BDK Native or a web-based approach using the Geolocation plugin. Set up a recurring workflow on the driver's page that runs every 10 to 15 seconds, captures their current location using the Geolocation element, and updates their Driver Profile's current_location and creates a new Driver Location Log entry. On the rider's side, poll the driver's latest location every 10 seconds to update the map marker.
The payment workflow uses Stripe. On ride completion, create a charge using the Stripe plugin for the final_fare amount. Then use Stripe Connect to transfer the driver's share (typically 75 to 80 percent) to their connected Stripe account. The platform keeps the remainder as commission. Set up the Stripe Connect onboarding flow in the driver registration process.
The rating workflow triggers after ride completion. Prompt both rider and driver to rate each other. When a rating is submitted, create the Rating record and recalculate the average_rating on the rated user's profile using a backend workflow that searches all their ratings and computes the new average.
UI Architecture and Page Structure
You need fundamentally different interfaces for riders and drivers. The rider experience needs a home page with a map and pickup/dropoff input fields, a ride confirmation page showing fare estimate and driver details, an active ride page with map tracking and status updates, a ride history page, and a profile/settings page. The driver experience needs an online/offline toggle dashboard, incoming ride request notifications, an active ride page with navigation to pickup then dropoff, earnings summary, and profile with vehicle management.
Use Bubble's single-page app approach with custom states to toggle between views. Set a custom state called "view" on the page with values like "home," "requesting," "tracking," and "completed." Show and hide groups based on this state. This gives smoother transitions than full page navigations and keeps the map element persistent.
For the map, use the Google Maps Extended plugin for more control over markers and routes. Plot the driver's location as a car icon marker and update it as new location data comes in. Draw route lines between pickup and dropoff using the Google Directions API via the API Connector plugin.
Privacy Rules
Riders should only see their own ride history and active ride details. Drivers should only see rides they have accepted or that are currently being offered to them. Driver personal information like phone numbers should only be visible to the rider once a ride is accepted. Rating details should only be visible to the user who received them. Financial data like earnings and payment details should be strictly scoped to the relevant user. Set up privacy rules on every data type with the default being no access and explicit conditions opening visibility only where needed.
The Real-Time Challenge
Bubble is not natively built for real-time applications the way Socket.io or Firebase are. But you can get close. Use Bubble's "Do every X seconds" workflow action to poll for updates. For the driver matching screen, poll every 3 to 5 seconds to check for new ride requests. For location tracking during a ride, poll every 10 seconds. This creates a near-real-time experience that works for most on-demand service apps. If you need true sub-second real-time updates, consider integrating with a service like Pusher via the API Connector.
Cost and Timeline
An Uber-style app on Bubble takes 10 to 16 weeks for an experienced developer. The location tracking and real-time elements add significant complexity compared to a standard marketplace. You will need Bubble's Growth plan at $119 per month minimum for backend workflows and API calls. Add costs for the Google Maps API (roughly $200 per month at moderate usage), Stripe fees, and any native wrapper like BDK Native if you want app store distribution. Budget $3,000 to $5,000 annually for platform and API costs.
Build or Hire
An Uber clone is one of the more complex Bubble projects. The real-time location tracking, payment splitting, and dual-interface architecture require solid Bubble experience. If you are new to Bubble, this is not the right first project. Even experienced Bubble developers will face architectural decisions around location tracking and performance that require careful planning.
Related guides:
Bubble twilio integration guide
how to build a fleet management with Bubble
If you are building an on-demand service app, talk to the Goodspeed Studio Bubble team. We have built service marketplaces with location tracking and know where the performance bottlenecks hide.
Focus on the Service Loop, Not the Tech Stack
You are not competing with Uber's engineering team. You are testing whether a specific on-demand service works in a specific market. Bubble lets you build the complete ride-request-to-payment loop and get it in front of real users in weeks. Start with basic location matching and manual fare calculation if needed. Automate and optimise after you have proven demand. Talk to our Bubble developers.

Harish Malhi
Founder of Goodspeed
Harish Malhi is the founder of Goodspeed, one of the top-rated Bubble agencies globally and winner of Bubble’s Agency of the Year award in 2024. He left Google to launch his first app, Diaspo, built entirely on Bubble, which gained press coverage from the BBC, ITV and more. Since then, he has helped ship over 200 products using Bubble, Framer, n8n and more - from internal tools to full-scale SaaS platforms. Harish now leads a team that helps founders and operators replace clunky workflows with fast, flexible software without writing a line of code.
Frequently Asked Questions (FAQs)
Can Bubble handle real-time GPS tracking for a ride app?
Bubble supports near-real-time tracking using the Geolocation plugin and polling workflows that update every 10 to 15 seconds. For true sub-second updates, you would need to integrate an external service like Pusher via the API Connector.
How do I handle driver payments and commission splits?
Use Stripe Connect. Each driver completes Stripe onboarding through your app. When a ride completes, charge the rider and automatically transfer the driver's share to their connected Stripe account. Your platform keeps the commission.
Can I publish a Bubble-built Uber clone to app stores?
Yes, using a native wrapper like BDK Native or by wrapping your Bubble web app in a native shell. This gives you access to device features like GPS and push notifications while keeping your Bubble backend.
How long does it take to build an Uber clone with Bubble?
An experienced Bubble developer needs 10 to 16 weeks. The real-time location features and dual rider/driver interfaces add complexity. Learning Bubble while building would extend this to 20 or more weeks.
What are the main limitations of building Uber on Bubble?
The biggest limitations are real-time performance (polling vs true real-time), complex route optimisation, and surge pricing algorithms. For most on-demand service MVPs, these limitations do not matter at launch scale.
How much does it cost to run an Uber clone on Bubble?
Budget $3,000 to $5,000 annually. That covers Bubble's Growth plan at $119 per month, Google Maps API at roughly $200 per month, Stripe transaction fees, and a native wrapper subscription if needed.
