Is Base44 right for marketplaces?
With caveats. Marketplaces lean on real-time more than most verticals, and Base44 covers it with two primitives. Record-change subscriptions through entities.subscribe() (docs.base44.com) put new bids, new messages, order-status changes and inventory counts on screen as they are written. Actors are stateful realtime rooms over WebSockets, one live instance per room id, built for presence, typing indicators, in-room chat and live auctions (Base44 actors docs). Service marketplaces and slow-moving B2B niches rarely need more than record updates. A live-auction or live-commerce product that depends on who is watching and who is typing runs those rooms on Actors, so load-test them at your expected concurrency before launch.
The honest read: Base44 is a fast way to validate whether your marketplace thesis works at all. If users won't list and won't book on the MVP, they won't book on a rebuilt v2 either. Use Base44 to disprove the demand-side hypothesis cheap. If you survive that test, load-test the real-time paths at your projected traffic before you decide whether to stay or migrate.
What you can build
Marketplaces that fit Base44's shape:
- Service marketplaces — hire a tutor, book a coach, find a consultant. Listings are static, booking is asynchronous, payment happens once per transaction. Polling-friendly.
- Curated directories — paid listings in a vertical niche (e.g., "best agencies for SaaS marketing"). Subscription-based seller side, free buyer side, lead-form handoff. Almost no real-time needs.
- B2B procurement — RFQ, quote, contract. Long-cycle, document-heavy, polling is fine.
- Lead-generation marketplaces — buyers fill a form, sellers buy access to the lead. Stripe one-time payment per lead purchased, no escrow.
- Live-auction marketplaces, after a load test (eBay-style, sneaker drops, NFT mints) — Base44's docs list live auctions and presence as Actor use cases, but sub-second bid ordering and who-is-watching presence are the product, so prove them at peak concurrency before you commit.
What does not fit:
- High-frequency booking (ride-hailing, food delivery) — real-time matching is the product.
- Chat-native marketplaces (Whatnot-style live commerce) — live video is the moat, and it would come from a third-party video service.
- Anything with regulated escrow (legal, real estate trust accounts) — compliance posture is wrong.
Critical patterns for marketplaces
1. Two-sided identity: users + seller_profiles
Every Base44 app starts with Admin and User roles, and you can add extra roles and fields (Base44 access docs). Marketplaces need users to be buyers, sellers, or both, which is easier to model as data than as a role. The pattern:
// Collections
users {
id, email, name, default_role: 'buyer' | 'seller'
}
seller_profiles {
id, user_id (FK), stripe_connect_account_id,
kyc_status: 'pending' | 'verified' | 'rejected',
payout_schedule: 'instant' | 'weekly' | 'monthly',
trust_tier: 'new' | 'verified' | 'top',
total_listings: number, total_sales: number, rating: number
}
listings {
id, seller_profile_id (FK), title, price_cents,
status: 'draft' | 'active' | 'sold' | 'archived',
// ... domain fields
}
orders {
id, listing_id, buyer_user_id, seller_profile_id,
amount_cents, fee_cents, escrow_status: 'held' | 'released' | 'refunded',
stripe_payment_intent_id
}
The discipline: every listing and order carries seller_profile_id, and each seller's user record carries the same id as a custom field, so an RLS rule can compare the two and enforce "you can only act on your own seller account." This pattern survives migration cleanly.
2. Escrow: Stripe Connect with manual capture
The flow that works:
Buyer creates order -> Base44 backend function creates PaymentIntent
with capture_method='manual', destination=seller_account
-> Stripe authorizes the buyer's card (funds held)
-> Order status: 'authorized'
Seller delivers -> Order moves to 'delivered'
Buyer confirms (or 7d) -> Backend function calls stripe.paymentIntents.capture()
(transfers minus platform fee to seller)
-> Order status: 'released'
Buyer disputes -> Backend function calls stripe.refunds.create()
-> Order status: 'refunded'
The capture window is the trap. Stripe holds authorizations for 7 days for cards. Disputes that drag past 7 days force you to capture-and-refund instead of release-or-cancel, which leaves a paper trail that complicates accounting. Build dispute handling into the order state machine from day one.
3. Search: filter UI now, Algolia later
Up to 5,000 listings, Base44's collection filters cover most search needs; 5,000 is also the most one list() or filter() request returns (docs.base44.com, read 25 Sep 2026). UI: category dropdown, price range, location filter, sort by created_at or price. Past 5,000, you sync to Algolia:
// On every listing write, in backend function:
async function syncListingToAlgolia(listing) {
await algolia.saveObject({
objectID: listing.id,
title: listing.title,
description: listing.description,
category: listing.category,
price: listing.price_cents / 100,
location: { lat: listing.lat, lng: listing.lng },
seller_trust_tier: listing.seller.trust_tier,
_tags: listing.tags,
});
}
Frontend queries Algolia directly with a search-only API key. Backend handles writes. Clean separation, $30–100/month at modest scale.
4. Real-time: subscriptions for records, Actors for live rooms
Anything that is a record — a bid, a chat message, an order moving to delivered — can stream through the SDK. entities.subscribe() delivers every create, update and delete on an entity, so filter to the auction on screen:
// Frontend: live bid list for one auction
const unsubscribe = base44.entities.Bid.subscribe((event) => {
if (event.type === 'create' && event.data.auction_id === auctionId) {
setBids((prev) => [event.data, ...prev]);
}
});
// Call unsubscribe() when the auction page unmounts
Presence and "X is typing" are not record changes, and they do not belong in entities. They belong in an Actor: a stateful realtime room over WebSockets, one live instance per room id, which Base44's docs list for presence, typing indicators, in-room chat and live auctions (Base44 actors docs). Give each order's conversation its own room:
// Frontend: the order's private chat room. order.room_id is a
// crypto.randomUUID() stored on the order, readable only by buyer and seller.
const conn = base44.actors.OrderChat(order.room_id).connect();
conn.subscribe((msg) => {
if (msg.type === 'typing') showTypingDots(msg);
});
conn.send({ type: 'typing' });
// Call conn.close() when the order page unmounts
There is no room-level auth: the room id is the admission control, so mint it with crypto.randomUUID() rather than reusing an order id, and keep it out of any list other users can read. Inside the actor, attribute messages to the verified conn.identity, never to a user id the client sends. Entities keep every record; the room carries only the state you would never store, such as who is online and who is typing. Write anything that matters, like a closing bid, from the actor to an entity, and load-test rooms at launch concurrency before a live auction depends on them.
5. Trust and safety: review queue + manual escalation
Marketplaces need moderation. There is no native moderation UI on Base44, so you build it:
- Every new listing, review, and chat message lands in a
moderation_queuecollection with statuspending. - A small admin UI (built on Base44, gated by an
is_adminflag on users) shows pending items with approve/reject buttons. - AI-assisted triage is straightforward: a backend function calls a moderation API (OpenAI moderation, Perspective) on write and auto-approves anything below a threshold.
Plan for 4–6 hours per week of human moderation work for any marketplace past 100 listings. The platform will not do this for you.
Limitations and gotchas
| Limitation | Impact | Workaround |
|---|---|---|
| Realtime needs the right primitive | Record subscriptions carry bids and messages, not presence or typing | entities.subscribe() for records; actors for presence, typing and live auctions; load-test before launch |
| Buyer-seller duality is yours to model | Default Admin and User roles do not describe a seller | Extra roles and fields, or a side-table seller_profiles |
| No full-text search | Search degrades past 5k listings | Algolia or Meilisearch |
| No native moderation | T&S is 100% custom | moderation_queue + admin UI |
5,000 items per list() or filter() request | Large catalogues are read in pages | Cursor pagination; bulkCreate(), upsert() or CSV import for bulk seller imports |
| AI-set data permissions can be too broad | Cross-seller data leak | Manual seller_profile_id filter on every rule; test it in preview |
| Scheduled automations stop at the 5-minute function limit | Long payout runs are cut off | Batch payouts across runs; confirm each run on the Logs page |
| Mobile app review | Base44's store build (Builder plan and up) is a web-view wrapper, which Apple's guideline 4.2 turns away when the app is not "particularly useful, unique, or 'app-like'"; in-app purchases are "Not yet" supported, so paid listings and paid lead access cannot be sold inside the app | Stripe stays fine for bookings and physical goods; sell digital extras on the web (App Store rejection guide) |
| No reputation system | Reviews are entirely yours to design | Build it; align with vertical norms |
The expensive mistake for a marketplace team: treating Stripe Connect webhooks as fire-and-forget. Point them at a backend function's own HTTP endpoint, verify the signature, make the handler idempotent so a retried event never pays a seller twice, and confirm each checkout on the success page instead of relying on webhooks alone.
Real-world example architecture
An example service-marketplace MVP on Base44:
Collections:
- users (id, email, default_role)
- seller_profiles (user_id, stripe_connect_id, kyc_status, trust_tier)
- listings (seller_profile_id, title, price, category, location)
- orders (listing_id, buyer_user_id, escrow_status, stripe_pi_id)
- messages (order_id, sender_user_id, body, read_at)
- reviews (order_id, rating, body, public)
- moderation_queue (entity_type, entity_id, status, reason)
- audit_events (actor, event, entity, ts)
Actors:
- OrderChat (one private room per order: presence, typing)
External services:
- Stripe Connect -> escrow + payouts
- Algolia (optional, post-5k) -> search
- Postmark -> transactional email
- Twilio -> SMS for booking confirmations
Key flows:
- Seller onboarding -> Stripe Connect Express -> KYC redirect -> seller_profile complete
- Listing creation -> moderation queue -> AI auto-approve OR human review
- Order placement -> Stripe authorize -> escrow held -> seller delivers -> capture
- Dispute -> refund flow -> dispute_events log -> manual review
- Payout -> Stripe Connect payout schedule -> webhook -> seller_profile total update
On our build tiers this stack is Standard ($9,000, 4–6 weeks) or Premium ($15,000, 6–10 weeks) work, depending on how much escrow and search integration it needs. Once listings approach the 5,000 search threshold above, the migration conversation starts.
Cost to ship
For a marketplace at 500 active listings, 200 monthly transactions, $50 average order:
| Line item | Monthly | One-time |
|---|---|---|
| Base44 Pro or Elite plan (when credits run out, the documented route is to upgrade or adjust your plan) | $80–200 | — |
| Stripe Connect fees (~$10k GMV) | $290 + $0.25/payout | — |
| Postmark | $50 | — |
| Algolia (deferred until 5k listings) | $0–50 | $1,500 setup if needed |
| Sentry | $26 | — |
| Manual moderation labor | $400–800 | — |
| Build (escrow, onboarding, search, T&S) | — | $9,000–15,000 |
| Total | ~$845–1,415/mo + per-payout fees | ~$9,000–15,000 |
Comparable Next.js + Supabase + Stripe + Algolia stack: $150–250/month operational, $30,000–50,000 initial build. Base44 is meaningfully cheaper to start, less expensive at scale only if you stay under the ceilings.
Migration off-ramp
The clean migration target is Next.js + Supabase + Algolia + Stripe Connect. Component model maps. Postgres gives you full-text search out of the box (you can defer Algolia). Supabase Realtime's Presence and Broadcast channels take over the who-is-online and typing features you ran on Actors. Stripe Connect carries over unchanged. We document the playbook in the Next.js + Supabase migration guide. Hired out, it is fixed-price on our published migration tiers: $12,000 for up to 20 tables with multi-role auth and Stripe (4–5 weeks), and $25,000+ for multi-tenant or SOC 2 / HIPAA-compatible work, quoted in a written proposal within one week. How deep the SDK calls leaked into the React components decides how much of the frontend gets rewritten.
Get this scoped
If you are building a marketplace on Base44 and want to know whether the architecture will hold up to your traffic projections, our standard build engagement covers the escrow, onboarding, and moderation plumbing end-to-end. Or if you have a marketplace already live and want a written assessment of where the scale ceilings will hit, the $497 production audit maps the failure modes against your actual data volumes.
Book a 15-minute call to scope your marketplace
Related
- Solutions hub — every Base44 vertical fit verdict in one matrix.
- Base44 for SaaS: multi-tenancy patterns
- Base44 for ecommerce: Stripe and inventory
- $497 production audit — written verdict on escrow, search, and scale ceilings for your marketplace.
- Stripe integration breaks after updates
- Base44 webhooks: the complete guide
- Bulk deletes at scale with deleteMany
- Migrate Base44 to Next.js + Supabase
- Written by the Lead Engineer at Base44Devs from marketplace audits and rebuilds.