Building a freelancer marketplace in Bubble involves creating gig listings, freelancer profiles with skills and portfolio, a client request and bidding system, milestone-based payments via Stripe, and a review system. This tutorial walks you through the complete database schema, UI components, and workflows needed to launch a Fiverr-style platform without writing code.
Overview: Building a Freelancer Marketplace in Bubble
This tutorial guides you through building a full freelancer marketplace — similar to Fiverr or Upwork — entirely in Bubble. You will create the database architecture for freelancers, clients, gigs, bids, milestones, and reviews. You will build the frontend for browsing gigs, submitting proposals, managing projects, and processing payments through Stripe.
Prerequisites
- A Bubble app on the Growth plan or higher (for backend workflows)
- A Stripe account connected via the Stripe plugin or API Connector
- Familiarity with Bubble Data Types, Repeating Groups, and workflows
- Understanding of Bubble privacy rules
Step-by-step guide
Design the marketplace database schema
Design the marketplace database schema
In the Data tab, create these Data Types: (1) UserProfile — extends User with fields: role (Option Set: Freelancer/Client), bio (text), hourly_rate (number), skills (list of Option Set: Skill), portfolio_images (list of images), rating_average (number), total_reviews (number). (2) Gig — fields: title (text), description (text), category (Option Set: Category), freelancer (User), price (number), delivery_days (number), is_active (yes/no). (3) Bid — fields: gig (Gig), client (User), message (text), budget (number), status (Option Set: BidStatus — Pending/Accepted/Rejected). (4) Project — fields: gig (Gig), client (User), freelancer (User), status (Option Set: ProjectStatus), total_amount (number). (5) Milestone — fields: project (Project), title (text), amount (number), status (Option Set: MilestoneStatus — Pending/InProgress/Completed/Paid). (6) Review — fields: project (Project), reviewer (User), reviewee (User), rating (number), comment (text).
Pro tip: Store rating_average as a field on UserProfile instead of calculating it from Reviews on every page load — this dramatically reduces workload units.
Expected result: Your database has all core Data Types with proper relationships to support gig listings, bidding, projects, milestones, and reviews.
Build the gig listing and search pages
Build the gig listing and search pages
Create a page called 'explore' with a search bar (Input element) and category filter (Dropdown with Option Set: Category as data source). Below, add a Repeating Group with data source: Do a Search for Gigs with constraints: is_active = yes, category = Dropdown's value (with Ignore empty constraints checked), title contains Search Input's value. Inside each cell, display the gig title, freelancer name, price, rating, and a thumbnail image. Link each cell to a 'gig-detail' page that receives the Gig as page data. Add pagination with a maximum of 12 items per page to keep load times fast.
Expected result: Users can browse, search, and filter active gig listings and click through to view gig details.
Create the freelancer profile and gig detail pages
Create the freelancer profile and gig detail pages
Create a 'gig-detail' page with page type set to Gig. Display the gig title, description, price, delivery time, and freelancer info. Add a Send Proposal button for clients. Create a 'profile' page with page type set to User. Display the freelancer's bio, skills (as tags using a Repeating Group with the skills list), portfolio images (in an image gallery Repeating Group), reviews (Repeating Group of Reviews where reviewee = Current Page User), and average rating. Include a Contact button that creates a direct message thread.
Expected result: Visitors can view complete gig details and freelancer profiles with portfolio, skills, and reviews.
Implement the bidding and project creation workflow
Implement the bidding and project creation workflow
On the gig-detail page, add a Proposal form (visible only when Current User's role is Client) with a message textarea and budget input. When the Submit Proposal button is clicked, create a new Bid with status = Pending. On the freelancer's dashboard, show incoming bids in a Repeating Group (Do a Search for Bids where gig's freelancer = Current User and status = Pending). Add Accept and Reject buttons in each cell. The Accept workflow should: (1) Change the Bid status to Accepted, (2) Create a new Project with status = Active, (3) Change all other Bids for this gig to Rejected. The Reject workflow simply changes the Bid status to Rejected.
Expected result: Clients can submit proposals on gigs, and freelancers can accept or reject bids from their dashboard.
Set up milestone-based payments with Stripe
Set up milestone-based payments with Stripe
When a project is created, the freelancer defines milestones from the project management page. Add a form with milestone title and amount fields. The workflow creates a Milestone with status = Pending. When a milestone is marked as Completed by the freelancer, the client sees a Release Payment button. This button triggers a Stripe charge using the Stripe plugin or API Connector — charging the milestone amount to the client's saved payment method and transferring funds to the freelancer's connected Stripe account. After successful payment, update the Milestone status to Paid. When all milestones are paid, update the Project status to Completed.
Pro tip: For complex payment flows like this, RapidDev can help you set up Stripe Connect to handle marketplace payments, platform fees, and automated payouts to freelancers.
Expected result: Payments are processed per milestone through Stripe, with funds released when clients approve completed work.
Build the review and rating system
Build the review and rating system
When a Project status changes to Completed, show a Leave Review prompt to both the client and freelancer. Create a review form with a star rating (1-5 using an Option Set or custom state) and a comment textarea. The Submit Review workflow creates a Review record and then updates the reviewee's rating_average field using the formula: (existing rating_average multiplied by total_reviews plus new rating) divided by (total_reviews plus 1). Also increment total_reviews by 1. Display reviews on the profile page sorted by newest first. Add privacy rules so only users involved in a completed project can leave reviews.
Expected result: Both parties can leave reviews after project completion, and average ratings update automatically on profiles.
Complete working example
1FREELANCER MARKETPLACE ARCHITECTURE2=====================================34DATA TYPES:5 UserProfile (extends User):6 - role: Option Set (Freelancer/Client)7 - bio: text8 - hourly_rate: number9 - skills: list of Option Set (Skill)10 - portfolio_images: list of images11 - rating_average: number12 - total_reviews: number1314 Gig:15 - title: text16 - description: text17 - category: Option Set (Category)18 - freelancer: User19 - price: number20 - delivery_days: number21 - is_active: yes/no2223 Bid:24 - gig: Gig25 - client: User26 - message: text27 - budget: number28 - status: Option Set (Pending/Accepted/Rejected)2930 Project:31 - gig: Gig32 - client: User33 - freelancer: User34 - status: Option Set (Active/InProgress/Completed/Cancelled)35 - total_amount: number3637 Milestone:38 - project: Project39 - title: text40 - amount: number41 - status: Option Set (Pending/InProgress/Completed/Paid)4243 Review:44 - project: Project45 - reviewer: User46 - reviewee: User47 - rating: number (1-5)48 - comment: text4950KEY WORKFLOWS:51 Submit Proposal:52 Trigger: Button click (client on gig page)53 → Create Bid (status: Pending)5455 Accept Bid:56 Trigger: Accept button (freelancer dashboard)57 → Change Bid status → Accepted58 → Create Project (status: Active)59 → Reject all other Bids for this gig6061 Release Milestone Payment:62 Trigger: Release Payment button (client)63 → Stripe charge (milestone amount)64 → Change Milestone status → Paid65 → If all milestones paid → Change Project status → Completed6667 Submit Review:68 Trigger: Submit button (after project completion)69 → Create Review70 → Update reviewee's rating_average and total_reviews7172PRIVACY RULES:73 Gig: Anyone can view active gigs74 Bid: Only gig freelancer and bid client can view75 Project: Only project client and freelancer can view76 Review: Anyone can view (read-only after creation)Common mistakes when building a freelancer marketplace in Bubble
Why it's a problem: Calculating average ratings with a search on every page load
How to avoid: Store rating_average as a field on UserProfile and update it incrementally when new reviews are submitted
Why it's a problem: Not setting privacy rules on Bids and Projects
How to avoid: Add privacy rules so Bids are visible only to the gig freelancer and bid client, and Projects are visible only to involved parties
Why it's a problem: Allowing reviews before project completion
How to avoid: Only show the review form and allow review creation when the Project status equals Completed
Best practices
- Store computed values like rating_average as fields rather than calculating on every page load
- Use Option Sets for statuses (BidStatus, ProjectStatus, MilestoneStatus) — they load faster than database lookups
- Set strict privacy rules on all Data Types — especially Bids, Projects, and financial data
- Paginate gig listings to 12-20 items per page to maintain fast load times
- Use backend workflows for payment processing and status changes to ensure they complete even if the user closes the browser
- Implement an escrow pattern where client funds are held until milestone approval
- Add an admin dashboard for dispute resolution and marketplace moderation
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a freelancer marketplace like Fiverr in Bubble.io. Help me design the database schema for freelancer profiles, gig listings, client proposals, project management with milestones, and a review system.
Create a gig listing page with a search bar and category filter. Display gigs in a Repeating Group showing the title, freelancer name, price, and rating. Add an Accept Proposal button on the freelancer dashboard that creates a Project and rejects other bids.
Frequently asked questions
What Bubble plan do I need for a freelancer marketplace?
The Growth plan or higher is recommended because marketplaces need backend workflows for payment processing, higher workload unit limits for search-heavy pages, and more storage for portfolio images.
How do I handle payments between clients and freelancers?
Use Stripe Connect to create a marketplace payment flow. Clients pay into your platform, and funds are held until milestones are approved, then transferred to the freelancer's connected Stripe account minus your platform fee.
Can I prevent fake reviews on my marketplace?
Yes. Only allow reviews when a Project has status Completed and both parties have been involved. Add a privacy rule so only the client and freelancer of a completed project can create reviews.
How do I scale a marketplace if it gets slow with many listings?
Paginate Repeating Groups, use database constraints instead of client-side filters, store computed values as fields, and consider Algolia for search via the OmniSearch plugin.
Can RapidDev help build a freelancer marketplace in Bubble?
Yes. RapidDev specializes in building complex marketplace applications including Stripe Connect integration, bidding systems, milestone payments, and review moderation — accelerating your time to launch significantly.
Should I use Stripe plugin or API Connector for payments?
For simple checkout flows, the Stripe plugin is easier. For marketplace payments with Connect, escrow, and split payouts, the API Connector gives you more control over the Stripe API endpoints.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation